@ai-dev-tools/csharp-copilot-core 0.0.38 → 0.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/gen/postGen/postGenMoreUTAutofixProcess.js +2 -0
- package/out/gen/postGen/postGenMoreUTAutofixProcess.js.map +1 -1
- package/out/gen/postGen/postGenMoreUTProcess.js +208 -4
- package/out/gen/postGen/postGenMoreUTProcess.js.map +1 -1
- package/out/utils/spawnExec.js +4 -1
- package/out/utils/spawnExec.js.map +1 -1
- package/package.json +1 -1
|
@@ -155,6 +155,8 @@ function postGenMoreUTAutofixProcess(generatedCode, testFramework, isXapCode, so
|
|
|
155
155
|
}
|
|
156
156
|
// ── Step 10 : Restore original line-ending style ────────────────────────
|
|
157
157
|
resultCode = resultCode.replace(/\n/g, lineEnding);
|
|
158
|
+
// ── Step 11 : Remove trailing whitespace from each line (trim_trailing_whitespace) ────
|
|
159
|
+
resultCode = resultCode.split(lineEnding).map(line => line.replace(/\s+$/, '')).join(lineEnding);
|
|
158
160
|
console.log(`postGenMoreUTAutofixProcess: completed, code length: ${resultCode.length}`);
|
|
159
161
|
return resultCode;
|
|
160
162
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postGenMoreUTAutofixProcess.js","sourceRoot":"","sources":["../../../src/gen/postGen/postGenMoreUTAutofixProcess.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\r\n\r\nimport { extractCodeFromResponse } from './extractCodeFromResponse';\r\nimport { removeCSharpOnlyLines } from './removeSingleLines';\r\nimport { repairRequiredNameSpaces, repairXapRequiredNameSpaces, repairUsingStatements } from './repairRequiredNameSpaces';\r\nimport { postGenProcess } from './postGenProcess';\r\nimport {\r\n detectLineEnding,\r\n detectTestMethodIndent,\r\n applyIndentation,\r\n findLastTestMethodEndLine,\r\n findTestClassInsertPosition,\r\n} from './postGenMoreUTProcess';\r\nimport { findTestMethodRangeByBrace, extractMethodName } from '../../utils/removeFailedTestMethods';\r\nimport { writeAIRawCode } from '../../utils/writeGenCode';\r\n\r\n// ─── Types ──────────────────────────────────────────────────────────────────────\r\n\r\ninterface MethodInfo {\r\n name: string;\r\n start: number; // 0-based inclusive\r\n end: number; // 0-based inclusive\r\n}\r\n\r\n// ─── Public entry point ─────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Post-process LLM response for the \"more UT auto-fix\" scenario.\r\n *\r\n * The LLM is asked to return the **complete** fixed test file, but it sometimes\r\n * omits unchanged test methods. This function performs a *surgical merge*:\r\n *\r\n * 1. Extract & clean the AI code from the markdown response.\r\n * 2. Replace **only** the error test methods in the original file with the\r\n * AI-fixed versions.\r\n * 3. Append any **new** test methods or helper methods that the AI added.\r\n * 4. Replace the `using` block wholesale with the AI's version.\r\n * 5. Apply standard namespace / Xap repairs.\r\n *\r\n * If `errorMethodNames` is empty or `testFilePath` is unavailable the function\r\n * falls back to standard `postGenProcess`-style processing.\r\n */\r\nexport function postGenMoreUTAutofixProcess(\r\n generatedCode: string,\r\n testFramework: string,\r\n isXapCode: boolean,\r\n sourceCode?: string,\r\n testFilePath?: string,\r\n errorMethodNames?: string[],\r\n): string {\r\n // ── Step 1 : Extract code from the AI response ──────────────────────────\r\n let aiCode = extractCodeFromResponse(generatedCode);\r\n if (!aiCode) {\r\n console.error('postGenMoreUTAutofixProcess: failed to extract code from AI response');\r\n return undefined;\r\n }\r\n aiCode = removeCSharpOnlyLines(aiCode);\r\n\r\n // Write AI raw response to atmpCache for debugging / auditing\r\n writeAIRawCode(aiCode, testFilePath);\r\n\r\n // ── Step 2 : Fallback when surgical merge is not possible ───────────────\r\n if (!errorMethodNames || errorMethodNames.length === 0) {\r\n console.log('postGenMoreUTAutofixProcess: no error method names, returning undefined');\r\n return undefined;\r\n }\r\n if (!testFilePath) {\r\n console.log('postGenMoreUTAutofixProcess: no test file path, returning undefined');\r\n return undefined;\r\n }\r\n if (!fs.existsSync(testFilePath)) {\r\n console.log(`postGenMoreUTAutofixProcess: test file not found (${testFilePath}), returning undefined`);\r\n return undefined;\r\n }\r\n\r\n // ── Step 3 : Read and normalise the original test file ──────────────────\r\n const originalCode = fs.readFileSync(testFilePath, 'utf-8');\r\n const lineEnding = detectLineEnding(originalCode);\r\n\r\n const normalizedAi = aiCode.replace(/\\r\\n/g, '\\n');\r\n const normalizedOriginal = originalCode.replace(/\\r\\n/g, '\\n');\r\n let resultLines = normalizedOriginal.split('\\n');\r\n const aiLines = normalizedAi.split('\\n');\r\n\r\n // ── Step 4 : Enumerate test methods in both files ───────────────────────\r\n const originalMethods = enumerateTestMethods(resultLines);\r\n const aiMethods = enumerateTestMethods(aiLines);\r\n\r\n console.log(`postGenMoreUTAutofixProcess: original has ${originalMethods.length} test method(s), AI has ${aiMethods.length} test method(s)`);\r\n console.log(`postGenMoreUTAutofixProcess: error methods: [${errorMethodNames.join(', ')}]`);\r\n\r\n // ── Step 5 : Replace error methods (bottom-to-top for index stability) ──\r\n // NOTE: This must happen BEFORE replaceUsingBlock, because originalMethods\r\n // indices were computed on the current resultLines. If the using block\r\n // has a different line count the indices would become stale.\r\n const baseIndent = detectTestMethodIndent(resultLines);\r\n\r\n const replacements = errorMethodNames\r\n .map(name => ({\r\n name,\r\n originalRange: originalMethods.find(m => m.name === name),\r\n aiRange: aiMethods.find(m => m.name === name),\r\n }))\r\n .filter(r => r.originalRange && r.aiRange)\r\n .sort((a, b) => b.originalRange.start - a.originalRange.start); // descending\r\n\r\n // If the AI didn't produce any of the error methods, the response is useless — signal retry\r\n if (replacements.length === 0) {\r\n const missingInAi = errorMethodNames.filter(n => !aiMethods.some(m => m.name === n));\r\n console.error(\r\n `postGenMoreUTAutofixProcess: AI response contains none of the ${errorMethodNames.length} ` +\r\n `error method(s), missing: [${missingInAi.join(', ')}]. Returning undefined to trigger retry.`,\r\n );\r\n return undefined;\r\n }\r\n\r\n for (const { name, originalRange, aiRange } of replacements) {\r\n const aiMethodText = aiLines.slice(aiRange.start, aiRange.end + 1);\r\n const reindented = applyIndentation(aiMethodText.join('\\n'), baseIndent).split('\\n');\r\n resultLines.splice(\r\n originalRange.start,\r\n originalRange.end - originalRange.start + 1,\r\n ...reindented,\r\n );\r\n console.log(\r\n ` replaced error method '${name}' (orig ${originalRange.start}-${originalRange.end}) ` +\r\n `with AI fix (${reindented.length} lines)`,\r\n );\r\n }\r\n\r\n // Log any error methods that couldn't be matched\r\n for (const name of errorMethodNames) {\r\n const inOrig = originalMethods.some(m => m.name === name);\r\n const inAi = aiMethods.some(m => m.name === name);\r\n if (!inOrig) console.warn(` error method '${name}' not found in original file`);\r\n if (!inAi) console.warn(` error method '${name}' not found in AI response`);\r\n }\r\n\r\n // ── Step 6 : Replace using block ────────────────────────────────────────\r\n // Done after method replacements so that originalMethods indices stay valid.\r\n resultLines = replaceUsingBlock(resultLines, aiLines);\r\n\r\n // ── Step 7 : Append new test methods from AI ────────────────────────────\r\n const originalMethodNames = new Set(originalMethods.map(m => m.name));\r\n const newTestMethods = aiMethods.filter(m => !originalMethodNames.has(m.name));\r\n\r\n if (newTestMethods.length > 0) {\r\n resultLines = appendMethodBlocks(\r\n resultLines,\r\n aiLines,\r\n newTestMethods,\r\n baseIndent,\r\n 'new test method',\r\n );\r\n }\r\n\r\n // ── Step 8 : Append new helper (non-test) methods from AI ───────────────\r\n const newHelpers = findNewHelperMethods(resultLines, aiLines, aiMethods);\r\n if (newHelpers.length > 0) {\r\n resultLines = appendMethodBlocks(\r\n resultLines,\r\n aiLines,\r\n newHelpers,\r\n baseIndent,\r\n 'new helper method',\r\n );\r\n }\r\n\r\n // ── Step 9 : Standard namespace / Xap / alias repairs ───────────────────\r\n let resultCode = resultLines.join('\\n');\r\n resultCode = repairRequiredNameSpaces(resultCode, testFramework);\r\n if (isXapCode) {\r\n resultCode = repairXapRequiredNameSpaces(resultCode);\r\n }\r\n if (sourceCode) {\r\n resultCode = repairUsingStatements(resultCode, sourceCode);\r\n }\r\n\r\n // ── Step 10 : Restore original line-ending style ────────────────────────\r\n resultCode = resultCode.replace(/\\n/g, lineEnding);\r\n console.log(`postGenMoreUTAutofixProcess: completed, code length: ${resultCode.length}`);\r\n return resultCode;\r\n}\r\n\r\n// ─── Internal helpers ───────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Standard fallback: apply the same processing as `postGenProcess`.\r\n */\r\nfunction fallbackPostProcess(\r\n aiCode: string,\r\n testFramework: string,\r\n isXapCode: boolean,\r\n sourceCode?: string,\r\n): string {\r\n return postGenProcess(aiCode, testFramework, isXapCode, sourceCode);\r\n}\r\n\r\n/**\r\n * Enumerate all test methods in the file by scanning for test-attribute lines\r\n * and using `findTestMethodRangeByBrace` to determine their full extent\r\n * (including all attributes above the method).\r\n */\r\nfunction enumerateTestMethods(lines: string[]): MethodInfo[] {\r\n const testPatterns = [\r\n /\\[TestMethod/i,\r\n /\\[Test\\]/i,\r\n /\\[Test\\(/i,\r\n /\\[Fact/i,\r\n /\\[Theory/i,\r\n ];\r\n\r\n const methods: MethodInfo[] = [];\r\n const visitedStarts = new Set<number>();\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const trimmed = lines[i].trim();\r\n const isTestAttr = testPatterns.some(p => p.test(trimmed));\r\n if (!isTestAttr) continue;\r\n\r\n const range = findTestMethodRangeByBrace(lines, i);\r\n if (!range || visitedStarts.has(range.start)) continue;\r\n visitedStarts.add(range.start);\r\n\r\n const name = findMethodNameInRange(lines, range.start, range.end);\r\n if (name) {\r\n methods.push({ name, start: range.start, end: range.end });\r\n }\r\n }\r\n\r\n return methods;\r\n}\r\n\r\n/**\r\n * Find the method name within a known method range by skipping attribute /\r\n * empty lines and reading the first real code line.\r\n */\r\nfunction findMethodNameInRange(lines: string[], start: number, end: number): string | null {\r\n for (let i = start; i <= end; i++) {\r\n const trimmed = lines[i].trim();\r\n if (trimmed === '' || trimmed.startsWith('[')) continue;\r\n // First non-attribute, non-empty line is the method signature\r\n const name = extractMethodName(trimmed);\r\n if (name) return name;\r\n }\r\n return null;\r\n}\r\n\r\n// ─── Using-block replacement ────────────────────────────────────────────────────\r\n\r\n/**\r\n * Find the contiguous `using` directive block at the top of the file.\r\n * Returns inclusive 0-based indices, or `null` when no usings are found.\r\n *\r\n * Skips blank lines and single-line comments (`//`) that appear between using\r\n * directives so that groups like:\r\n *\r\n * using System;\r\n * // collections\r\n * using System.Collections.Generic;\r\n *\r\n * are treated as one block.\r\n */\r\nfunction findUsingBlockRange(lines: string[]): { start: number; end: number } | null {\r\n let start = -1;\r\n let end = -1;\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const trimmed = lines[i].trim();\r\n\r\n if (isUsingDirective(trimmed)) {\r\n if (start === -1) start = i;\r\n end = i;\r\n } else if (start !== -1) {\r\n // Allow blank lines and single-line comments inside the using block\r\n if (trimmed === '' || trimmed.startsWith('//')) continue;\r\n // Any other content means the using block has ended\r\n break;\r\n }\r\n }\r\n\r\n return start === -1 ? null : { start, end };\r\n}\r\n\r\n/**\r\n * Check whether a trimmed line is a `using` directive (not a `using` statement\r\n * such as `using (var x = ...)`).\r\n */\r\nfunction isUsingDirective(trimmed: string): boolean {\r\n return (trimmed.startsWith('using ') || trimmed.startsWith('using\\t'))\r\n && !trimmed.includes('(')\r\n && trimmed.endsWith(';');\r\n}\r\n\r\n/**\r\n * Replace the original file's using block with the AI response's using block.\r\n * If the AI has no usings the original is returned unchanged.\r\n */\r\nfunction replaceUsingBlock(originalLines: string[], aiLines: string[]): string[] {\r\n const aiRange = findUsingBlockRange(aiLines);\r\n if (!aiRange) return [...originalLines];\r\n\r\n const aiUsings = aiLines.slice(aiRange.start, aiRange.end + 1);\r\n const origRange = findUsingBlockRange(originalLines);\r\n\r\n const result = [...originalLines];\r\n if (origRange) {\r\n result.splice(origRange.start, origRange.end - origRange.start + 1, ...aiUsings);\r\n } else {\r\n // No usings in original – prepend\r\n result.splice(0, 0, ...aiUsings, '');\r\n }\r\n console.log(` replaced using block (${aiUsings.length} lines from AI)`);\r\n return result;\r\n}\r\n\r\n// ─── Appending new method blocks ────────────────────────────────────────────────\r\n\r\n/**\r\n * Append method blocks (described by `methods` referencing `aiLines`) into\r\n * `resultLines` right after the last test method.\r\n */\r\nfunction appendMethodBlocks(\r\n resultLines: string[],\r\n aiLines: string[],\r\n methods: MethodInfo[],\r\n baseIndent: string,\r\n label: string,\r\n): string[] {\r\n let insertLine = findLastTestMethodEndLine(resultLines);\r\n if (insertLine === 0) {\r\n insertLine = findTestClassInsertPosition(resultLines);\r\n }\r\n if (insertLine === 0) {\r\n console.warn(` could not find insert position for ${label}(s), skipping`);\r\n return resultLines;\r\n }\r\n\r\n const insertIndex = insertLine - 1; // 1-based → 0-based\r\n const newLines: string[] = [];\r\n\r\n for (const m of methods) {\r\n const raw = aiLines.slice(m.start, m.end + 1).join('\\n');\r\n const reindented = applyIndentation(raw, baseIndent);\r\n newLines.push('', ...reindented.split('\\n'));\r\n console.log(` appended ${label} '${m.name}' (${m.end - m.start + 1} lines)`);\r\n }\r\n\r\n const result = [...resultLines];\r\n result.splice(insertIndex, 0, ...newLines);\r\n return result;\r\n}\r\n\r\n// ─── New helper method detection ────────────────────────────────────────────────\r\n\r\n/**\r\n * Find non-test methods in the AI response that do **not** exist in the\r\n * original / result file. These are typically helper or factory methods that\r\n * the AI introduced to support the fixed test code.\r\n *\r\n * Detection strategy:\r\n * 1. Mark every line in `aiLines` that belongs to a known test method.\r\n * 2. Inside the class body, scan the unclaimed lines for method signatures.\r\n * 3. Brace-match to determine the full method extent.\r\n * 4. Keep only methods whose name does not appear in `resultLines`.\r\n */\r\nfunction findNewHelperMethods(\r\n resultLines: string[],\r\n aiLines: string[],\r\n aiTestMethods: MethodInfo[],\r\n): MethodInfo[] {\r\n // Lines already claimed by test methods\r\n const claimed = new Set<number>();\r\n for (const m of aiTestMethods) {\r\n for (let i = m.start; i <= m.end; i++) claimed.add(i);\r\n }\r\n\r\n // Approximate class body range in AI: from first `{` after a `class` keyword\r\n // to the matching `}`.\r\n const classBody = findClassBodyRange(aiLines);\r\n if (!classBody) return [];\r\n\r\n // Collect existing method names from the result file for comparison\r\n const existingNames = collectAllMethodNames(resultLines);\r\n\r\n const methodSigPattern = /^\\s*(public|private|protected|internal)\\s+/;\r\n const helpers: MethodInfo[] = [];\r\n const attributePattern = /^\\s*\\[.+\\]\\s*$/;\r\n\r\n for (let i = classBody.start; i <= classBody.end; i++) {\r\n if (claimed.has(i)) continue;\r\n const line = aiLines[i];\r\n if (!methodSigPattern.test(line)) continue;\r\n\r\n // Must look like a method: name followed by `(`\r\n const name = extractMethodName(line.trim());\r\n if (!name || existingNames.has(name)) continue;\r\n\r\n // Check this isn't a property (contains `{ get` or `{ set` on same/next line)\r\n if (isPropertyDeclaration(aiLines, i)) continue;\r\n\r\n // Brace-match to find method end\r\n const end = braceMatchForward(aiLines, i, classBody.end);\r\n if (end === -1) continue;\r\n\r\n // Search upward for preceding attributes\r\n let start = i;\r\n for (let k = i - 1; k >= classBody.start; k--) {\r\n const t = aiLines[k].trim();\r\n if (attributePattern.test(t)) { start = k; }\r\n else if (t === '') { /* skip blank lines between attrs */ }\r\n else break;\r\n }\r\n\r\n helpers.push({ name, start, end });\r\n\r\n // Mark as claimed so we don't double-count\r\n for (let k = start; k <= end; k++) claimed.add(k);\r\n }\r\n\r\n return helpers;\r\n}\r\n\r\n/**\r\n * Find the class body range (the lines between the opening `{` of the test\r\n * class and its matching `}`). Returns 0-based inclusive indices.\r\n */\r\nfunction findClassBodyRange(lines: string[]): { start: number; end: number } | null {\r\n const classPattern = /^\\s*(public\\s+)?(partial\\s+)?(static\\s+)?class\\s+/i;\r\n\r\n let classLineIdx = -1;\r\n for (let i = 0; i < lines.length; i++) {\r\n if (classPattern.test(lines[i])) { classLineIdx = i; break; }\r\n }\r\n if (classLineIdx === -1) return null;\r\n\r\n // Find opening brace\r\n let openIdx = -1;\r\n for (let i = classLineIdx; i < lines.length; i++) {\r\n if (lines[i].includes('{')) { openIdx = i; break; }\r\n }\r\n if (openIdx === -1) return null;\r\n\r\n // Brace-match to find the class closing brace\r\n let depth = 0;\r\n let closeIdx = -1;\r\n for (let i = openIdx; i < lines.length; i++) {\r\n for (const ch of lines[i]) {\r\n if (ch === '{') depth++;\r\n if (ch === '}') { depth--; if (depth === 0) { closeIdx = i; break; } }\r\n }\r\n if (closeIdx !== -1) break;\r\n }\r\n if (closeIdx === -1) return null;\r\n\r\n return { start: openIdx + 1, end: closeIdx - 1 };\r\n}\r\n\r\n/**\r\n * Collect all method-like names from a file (test + non-test) for de-duplication.\r\n */\r\nfunction collectAllMethodNames(lines: string[]): Set<string> {\r\n const names = new Set<string>();\r\n const methodSigPattern = /^\\s*(public|private|protected|internal)\\s+/;\r\n\r\n for (const line of lines) {\r\n if (!methodSigPattern.test(line)) continue;\r\n if (isLikelyFieldOrProperty(line)) continue;\r\n const name = extractMethodName(line.trim());\r\n if (name) names.add(name);\r\n }\r\n return names;\r\n}\r\n\r\n/** Simple heuristic to skip field or property declarations. */\r\nfunction isLikelyFieldOrProperty(line: string): boolean {\r\n const trimmed = line.trim();\r\n // Properties: `public int Foo { get; set; }`\r\n if (/\\{\\s*(get|set)/.test(trimmed)) return true;\r\n // Fields: `private readonly int _foo;` or `private int foo = ...;`\r\n if (trimmed.endsWith(';') && !trimmed.includes('(')) return true;\r\n return false;\r\n}\r\n\r\n/** Check whether line `i` starts a property (has `{ get` or `{ set`). */\r\nfunction isPropertyDeclaration(lines: string[], i: number): boolean {\r\n // Check current line and next line for property-style braces\r\n for (let k = i; k < Math.min(i + 3, lines.length); k++) {\r\n if (/\\{\\s*(get|set)/.test(lines[k])) return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Forward brace-match starting from line `start`. Returns the 0-based line\r\n * index of the closing `}`, or -1 on failure.\r\n */\r\nfunction braceMatchForward(lines: string[], start: number, maxLine: number): number {\r\n let depth = 0;\r\n let foundOpen = false;\r\n\r\n for (let i = start; i <= maxLine; i++) {\r\n for (const ch of lines[i]) {\r\n if (ch === '{') { depth++; foundOpen = true; }\r\n if (ch === '}') {\r\n depth--;\r\n if (foundOpen && depth === 0) return i;\r\n }\r\n }\r\n }\r\n return -1;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"postGenMoreUTAutofixProcess.js","sourceRoot":"","sources":["../../../src/gen/postGen/postGenMoreUTAutofixProcess.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\r\n\r\nimport { extractCodeFromResponse } from './extractCodeFromResponse';\r\nimport { removeCSharpOnlyLines } from './removeSingleLines';\r\nimport { repairRequiredNameSpaces, repairXapRequiredNameSpaces, repairUsingStatements } from './repairRequiredNameSpaces';\r\nimport { postGenProcess } from './postGenProcess';\r\nimport {\r\n detectLineEnding,\r\n detectTestMethodIndent,\r\n applyIndentation,\r\n findLastTestMethodEndLine,\r\n findTestClassInsertPosition,\r\n} from './postGenMoreUTProcess';\r\nimport { findTestMethodRangeByBrace, extractMethodName } from '../../utils/removeFailedTestMethods';\r\nimport { writeAIRawCode } from '../../utils/writeGenCode';\r\n\r\n// ─── Types ──────────────────────────────────────────────────────────────────────\r\n\r\ninterface MethodInfo {\r\n name: string;\r\n start: number; // 0-based inclusive\r\n end: number; // 0-based inclusive\r\n}\r\n\r\n// ─── Public entry point ─────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Post-process LLM response for the \"more UT auto-fix\" scenario.\r\n *\r\n * The LLM is asked to return the **complete** fixed test file, but it sometimes\r\n * omits unchanged test methods. This function performs a *surgical merge*:\r\n *\r\n * 1. Extract & clean the AI code from the markdown response.\r\n * 2. Replace **only** the error test methods in the original file with the\r\n * AI-fixed versions.\r\n * 3. Append any **new** test methods or helper methods that the AI added.\r\n * 4. Replace the `using` block wholesale with the AI's version.\r\n * 5. Apply standard namespace / Xap repairs.\r\n *\r\n * If `errorMethodNames` is empty or `testFilePath` is unavailable the function\r\n * falls back to standard `postGenProcess`-style processing.\r\n */\r\nexport function postGenMoreUTAutofixProcess(\r\n generatedCode: string,\r\n testFramework: string,\r\n isXapCode: boolean,\r\n sourceCode?: string,\r\n testFilePath?: string,\r\n errorMethodNames?: string[],\r\n): string {\r\n // ── Step 1 : Extract code from the AI response ──────────────────────────\r\n let aiCode = extractCodeFromResponse(generatedCode);\r\n if (!aiCode) {\r\n console.error('postGenMoreUTAutofixProcess: failed to extract code from AI response');\r\n return undefined;\r\n }\r\n aiCode = removeCSharpOnlyLines(aiCode);\r\n\r\n // Write AI raw response to atmpCache for debugging / auditing\r\n writeAIRawCode(aiCode, testFilePath);\r\n\r\n // ── Step 2 : Fallback when surgical merge is not possible ───────────────\r\n if (!errorMethodNames || errorMethodNames.length === 0) {\r\n console.log('postGenMoreUTAutofixProcess: no error method names, returning undefined');\r\n return undefined;\r\n }\r\n if (!testFilePath) {\r\n console.log('postGenMoreUTAutofixProcess: no test file path, returning undefined');\r\n return undefined;\r\n }\r\n if (!fs.existsSync(testFilePath)) {\r\n console.log(`postGenMoreUTAutofixProcess: test file not found (${testFilePath}), returning undefined`);\r\n return undefined;\r\n }\r\n\r\n // ── Step 3 : Read and normalise the original test file ──────────────────\r\n const originalCode = fs.readFileSync(testFilePath, 'utf-8');\r\n const lineEnding = detectLineEnding(originalCode);\r\n\r\n const normalizedAi = aiCode.replace(/\\r\\n/g, '\\n');\r\n const normalizedOriginal = originalCode.replace(/\\r\\n/g, '\\n');\r\n let resultLines = normalizedOriginal.split('\\n');\r\n const aiLines = normalizedAi.split('\\n');\r\n\r\n // ── Step 4 : Enumerate test methods in both files ───────────────────────\r\n const originalMethods = enumerateTestMethods(resultLines);\r\n const aiMethods = enumerateTestMethods(aiLines);\r\n\r\n console.log(`postGenMoreUTAutofixProcess: original has ${originalMethods.length} test method(s), AI has ${aiMethods.length} test method(s)`);\r\n console.log(`postGenMoreUTAutofixProcess: error methods: [${errorMethodNames.join(', ')}]`);\r\n\r\n // ── Step 5 : Replace error methods (bottom-to-top for index stability) ──\r\n // NOTE: This must happen BEFORE replaceUsingBlock, because originalMethods\r\n // indices were computed on the current resultLines. If the using block\r\n // has a different line count the indices would become stale.\r\n const baseIndent = detectTestMethodIndent(resultLines);\r\n\r\n const replacements = errorMethodNames\r\n .map(name => ({\r\n name,\r\n originalRange: originalMethods.find(m => m.name === name),\r\n aiRange: aiMethods.find(m => m.name === name),\r\n }))\r\n .filter(r => r.originalRange && r.aiRange)\r\n .sort((a, b) => b.originalRange.start - a.originalRange.start); // descending\r\n\r\n // If the AI didn't produce any of the error methods, the response is useless — signal retry\r\n if (replacements.length === 0) {\r\n const missingInAi = errorMethodNames.filter(n => !aiMethods.some(m => m.name === n));\r\n console.error(\r\n `postGenMoreUTAutofixProcess: AI response contains none of the ${errorMethodNames.length} ` +\r\n `error method(s), missing: [${missingInAi.join(', ')}]. Returning undefined to trigger retry.`,\r\n );\r\n return undefined;\r\n }\r\n\r\n for (const { name, originalRange, aiRange } of replacements) {\r\n const aiMethodText = aiLines.slice(aiRange.start, aiRange.end + 1);\r\n const reindented = applyIndentation(aiMethodText.join('\\n'), baseIndent).split('\\n');\r\n resultLines.splice(\r\n originalRange.start,\r\n originalRange.end - originalRange.start + 1,\r\n ...reindented,\r\n );\r\n console.log(\r\n ` replaced error method '${name}' (orig ${originalRange.start}-${originalRange.end}) ` +\r\n `with AI fix (${reindented.length} lines)`,\r\n );\r\n }\r\n\r\n // Log any error methods that couldn't be matched\r\n for (const name of errorMethodNames) {\r\n const inOrig = originalMethods.some(m => m.name === name);\r\n const inAi = aiMethods.some(m => m.name === name);\r\n if (!inOrig) console.warn(` error method '${name}' not found in original file`);\r\n if (!inAi) console.warn(` error method '${name}' not found in AI response`);\r\n }\r\n\r\n // ── Step 6 : Replace using block ────────────────────────────────────────\r\n // Done after method replacements so that originalMethods indices stay valid.\r\n resultLines = replaceUsingBlock(resultLines, aiLines);\r\n\r\n // ── Step 7 : Append new test methods from AI ────────────────────────────\r\n const originalMethodNames = new Set(originalMethods.map(m => m.name));\r\n const newTestMethods = aiMethods.filter(m => !originalMethodNames.has(m.name));\r\n\r\n if (newTestMethods.length > 0) {\r\n resultLines = appendMethodBlocks(\r\n resultLines,\r\n aiLines,\r\n newTestMethods,\r\n baseIndent,\r\n 'new test method',\r\n );\r\n }\r\n\r\n // ── Step 8 : Append new helper (non-test) methods from AI ───────────────\r\n const newHelpers = findNewHelperMethods(resultLines, aiLines, aiMethods);\r\n if (newHelpers.length > 0) {\r\n resultLines = appendMethodBlocks(\r\n resultLines,\r\n aiLines,\r\n newHelpers,\r\n baseIndent,\r\n 'new helper method',\r\n );\r\n }\r\n\r\n // ── Step 9 : Standard namespace / Xap / alias repairs ───────────────────\r\n let resultCode = resultLines.join('\\n');\r\n resultCode = repairRequiredNameSpaces(resultCode, testFramework);\r\n if (isXapCode) {\r\n resultCode = repairXapRequiredNameSpaces(resultCode);\r\n }\r\n if (sourceCode) {\r\n resultCode = repairUsingStatements(resultCode, sourceCode);\r\n }\r\n\r\n // ── Step 10 : Restore original line-ending style ────────────────────────\r\n resultCode = resultCode.replace(/\\n/g, lineEnding);\r\n \r\n // ── Step 11 : Remove trailing whitespace from each line (trim_trailing_whitespace) ────\r\n resultCode = resultCode.split(lineEnding).map(line => line.replace(/\\s+$/, '')).join(lineEnding);\r\n \r\n console.log(`postGenMoreUTAutofixProcess: completed, code length: ${resultCode.length}`);\r\n return resultCode;\r\n}\r\n\r\n// ─── Internal helpers ───────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Standard fallback: apply the same processing as `postGenProcess`.\r\n */\r\nfunction fallbackPostProcess(\r\n aiCode: string,\r\n testFramework: string,\r\n isXapCode: boolean,\r\n sourceCode?: string,\r\n): string {\r\n return postGenProcess(aiCode, testFramework, isXapCode, sourceCode);\r\n}\r\n\r\n/**\r\n * Enumerate all test methods in the file by scanning for test-attribute lines\r\n * and using `findTestMethodRangeByBrace` to determine their full extent\r\n * (including all attributes above the method).\r\n */\r\nfunction enumerateTestMethods(lines: string[]): MethodInfo[] {\r\n const testPatterns = [\r\n /\\[TestMethod/i,\r\n /\\[Test\\]/i,\r\n /\\[Test\\(/i,\r\n /\\[Fact/i,\r\n /\\[Theory/i,\r\n ];\r\n\r\n const methods: MethodInfo[] = [];\r\n const visitedStarts = new Set<number>();\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const trimmed = lines[i].trim();\r\n const isTestAttr = testPatterns.some(p => p.test(trimmed));\r\n if (!isTestAttr) continue;\r\n\r\n const range = findTestMethodRangeByBrace(lines, i);\r\n if (!range || visitedStarts.has(range.start)) continue;\r\n visitedStarts.add(range.start);\r\n\r\n const name = findMethodNameInRange(lines, range.start, range.end);\r\n if (name) {\r\n methods.push({ name, start: range.start, end: range.end });\r\n }\r\n }\r\n\r\n return methods;\r\n}\r\n\r\n/**\r\n * Find the method name within a known method range by skipping attribute /\r\n * empty lines and reading the first real code line.\r\n */\r\nfunction findMethodNameInRange(lines: string[], start: number, end: number): string | null {\r\n for (let i = start; i <= end; i++) {\r\n const trimmed = lines[i].trim();\r\n if (trimmed === '' || trimmed.startsWith('[')) continue;\r\n // First non-attribute, non-empty line is the method signature\r\n const name = extractMethodName(trimmed);\r\n if (name) return name;\r\n }\r\n return null;\r\n}\r\n\r\n// ─── Using-block replacement ────────────────────────────────────────────────────\r\n\r\n/**\r\n * Find the contiguous `using` directive block at the top of the file.\r\n * Returns inclusive 0-based indices, or `null` when no usings are found.\r\n *\r\n * Skips blank lines and single-line comments (`//`) that appear between using\r\n * directives so that groups like:\r\n *\r\n * using System;\r\n * // collections\r\n * using System.Collections.Generic;\r\n *\r\n * are treated as one block.\r\n */\r\nfunction findUsingBlockRange(lines: string[]): { start: number; end: number } | null {\r\n let start = -1;\r\n let end = -1;\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const trimmed = lines[i].trim();\r\n\r\n if (isUsingDirective(trimmed)) {\r\n if (start === -1) start = i;\r\n end = i;\r\n } else if (start !== -1) {\r\n // Allow blank lines and single-line comments inside the using block\r\n if (trimmed === '' || trimmed.startsWith('//')) continue;\r\n // Any other content means the using block has ended\r\n break;\r\n }\r\n }\r\n\r\n return start === -1 ? null : { start, end };\r\n}\r\n\r\n/**\r\n * Check whether a trimmed line is a `using` directive (not a `using` statement\r\n * such as `using (var x = ...)`).\r\n */\r\nfunction isUsingDirective(trimmed: string): boolean {\r\n return (trimmed.startsWith('using ') || trimmed.startsWith('using\\t'))\r\n && !trimmed.includes('(')\r\n && trimmed.endsWith(';');\r\n}\r\n\r\n/**\r\n * Replace the original file's using block with the AI response's using block.\r\n * If the AI has no usings the original is returned unchanged.\r\n */\r\nfunction replaceUsingBlock(originalLines: string[], aiLines: string[]): string[] {\r\n const aiRange = findUsingBlockRange(aiLines);\r\n if (!aiRange) return [...originalLines];\r\n\r\n const aiUsings = aiLines.slice(aiRange.start, aiRange.end + 1);\r\n const origRange = findUsingBlockRange(originalLines);\r\n\r\n const result = [...originalLines];\r\n if (origRange) {\r\n result.splice(origRange.start, origRange.end - origRange.start + 1, ...aiUsings);\r\n } else {\r\n // No usings in original – prepend\r\n result.splice(0, 0, ...aiUsings, '');\r\n }\r\n console.log(` replaced using block (${aiUsings.length} lines from AI)`);\r\n return result;\r\n}\r\n\r\n// ─── Appending new method blocks ────────────────────────────────────────────────\r\n\r\n/**\r\n * Append method blocks (described by `methods` referencing `aiLines`) into\r\n * `resultLines` right after the last test method.\r\n */\r\nfunction appendMethodBlocks(\r\n resultLines: string[],\r\n aiLines: string[],\r\n methods: MethodInfo[],\r\n baseIndent: string,\r\n label: string,\r\n): string[] {\r\n let insertLine = findLastTestMethodEndLine(resultLines);\r\n if (insertLine === 0) {\r\n insertLine = findTestClassInsertPosition(resultLines);\r\n }\r\n if (insertLine === 0) {\r\n console.warn(` could not find insert position for ${label}(s), skipping`);\r\n return resultLines;\r\n }\r\n\r\n const insertIndex = insertLine - 1; // 1-based → 0-based\r\n const newLines: string[] = [];\r\n\r\n for (const m of methods) {\r\n const raw = aiLines.slice(m.start, m.end + 1).join('\\n');\r\n const reindented = applyIndentation(raw, baseIndent);\r\n newLines.push('', ...reindented.split('\\n'));\r\n console.log(` appended ${label} '${m.name}' (${m.end - m.start + 1} lines)`);\r\n }\r\n\r\n const result = [...resultLines];\r\n result.splice(insertIndex, 0, ...newLines);\r\n return result;\r\n}\r\n\r\n// ─── New helper method detection ────────────────────────────────────────────────\r\n\r\n/**\r\n * Find non-test methods in the AI response that do **not** exist in the\r\n * original / result file. These are typically helper or factory methods that\r\n * the AI introduced to support the fixed test code.\r\n *\r\n * Detection strategy:\r\n * 1. Mark every line in `aiLines` that belongs to a known test method.\r\n * 2. Inside the class body, scan the unclaimed lines for method signatures.\r\n * 3. Brace-match to determine the full method extent.\r\n * 4. Keep only methods whose name does not appear in `resultLines`.\r\n */\r\nfunction findNewHelperMethods(\r\n resultLines: string[],\r\n aiLines: string[],\r\n aiTestMethods: MethodInfo[],\r\n): MethodInfo[] {\r\n // Lines already claimed by test methods\r\n const claimed = new Set<number>();\r\n for (const m of aiTestMethods) {\r\n for (let i = m.start; i <= m.end; i++) claimed.add(i);\r\n }\r\n\r\n // Approximate class body range in AI: from first `{` after a `class` keyword\r\n // to the matching `}`.\r\n const classBody = findClassBodyRange(aiLines);\r\n if (!classBody) return [];\r\n\r\n // Collect existing method names from the result file for comparison\r\n const existingNames = collectAllMethodNames(resultLines);\r\n\r\n const methodSigPattern = /^\\s*(public|private|protected|internal)\\s+/;\r\n const helpers: MethodInfo[] = [];\r\n const attributePattern = /^\\s*\\[.+\\]\\s*$/;\r\n\r\n for (let i = classBody.start; i <= classBody.end; i++) {\r\n if (claimed.has(i)) continue;\r\n const line = aiLines[i];\r\n if (!methodSigPattern.test(line)) continue;\r\n\r\n // Must look like a method: name followed by `(`\r\n const name = extractMethodName(line.trim());\r\n if (!name || existingNames.has(name)) continue;\r\n\r\n // Check this isn't a property (contains `{ get` or `{ set` on same/next line)\r\n if (isPropertyDeclaration(aiLines, i)) continue;\r\n\r\n // Brace-match to find method end\r\n const end = braceMatchForward(aiLines, i, classBody.end);\r\n if (end === -1) continue;\r\n\r\n // Search upward for preceding attributes\r\n let start = i;\r\n for (let k = i - 1; k >= classBody.start; k--) {\r\n const t = aiLines[k].trim();\r\n if (attributePattern.test(t)) { start = k; }\r\n else if (t === '') { /* skip blank lines between attrs */ }\r\n else break;\r\n }\r\n\r\n helpers.push({ name, start, end });\r\n\r\n // Mark as claimed so we don't double-count\r\n for (let k = start; k <= end; k++) claimed.add(k);\r\n }\r\n\r\n return helpers;\r\n}\r\n\r\n/**\r\n * Find the class body range (the lines between the opening `{` of the test\r\n * class and its matching `}`). Returns 0-based inclusive indices.\r\n */\r\nfunction findClassBodyRange(lines: string[]): { start: number; end: number } | null {\r\n const classPattern = /^\\s*(public\\s+)?(partial\\s+)?(static\\s+)?class\\s+/i;\r\n\r\n let classLineIdx = -1;\r\n for (let i = 0; i < lines.length; i++) {\r\n if (classPattern.test(lines[i])) { classLineIdx = i; break; }\r\n }\r\n if (classLineIdx === -1) return null;\r\n\r\n // Find opening brace\r\n let openIdx = -1;\r\n for (let i = classLineIdx; i < lines.length; i++) {\r\n if (lines[i].includes('{')) { openIdx = i; break; }\r\n }\r\n if (openIdx === -1) return null;\r\n\r\n // Brace-match to find the class closing brace\r\n let depth = 0;\r\n let closeIdx = -1;\r\n for (let i = openIdx; i < lines.length; i++) {\r\n for (const ch of lines[i]) {\r\n if (ch === '{') depth++;\r\n if (ch === '}') { depth--; if (depth === 0) { closeIdx = i; break; } }\r\n }\r\n if (closeIdx !== -1) break;\r\n }\r\n if (closeIdx === -1) return null;\r\n\r\n return { start: openIdx + 1, end: closeIdx - 1 };\r\n}\r\n\r\n/**\r\n * Collect all method-like names from a file (test + non-test) for de-duplication.\r\n */\r\nfunction collectAllMethodNames(lines: string[]): Set<string> {\r\n const names = new Set<string>();\r\n const methodSigPattern = /^\\s*(public|private|protected|internal)\\s+/;\r\n\r\n for (const line of lines) {\r\n if (!methodSigPattern.test(line)) continue;\r\n if (isLikelyFieldOrProperty(line)) continue;\r\n const name = extractMethodName(line.trim());\r\n if (name) names.add(name);\r\n }\r\n return names;\r\n}\r\n\r\n/** Simple heuristic to skip field or property declarations. */\r\nfunction isLikelyFieldOrProperty(line: string): boolean {\r\n const trimmed = line.trim();\r\n // Properties: `public int Foo { get; set; }`\r\n if (/\\{\\s*(get|set)/.test(trimmed)) return true;\r\n // Fields: `private readonly int _foo;` or `private int foo = ...;`\r\n if (trimmed.endsWith(';') && !trimmed.includes('(')) return true;\r\n return false;\r\n}\r\n\r\n/** Check whether line `i` starts a property (has `{ get` or `{ set`). */\r\nfunction isPropertyDeclaration(lines: string[], i: number): boolean {\r\n // Check current line and next line for property-style braces\r\n for (let k = i; k < Math.min(i + 3, lines.length); k++) {\r\n if (/\\{\\s*(get|set)/.test(lines[k])) return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Forward brace-match starting from line `start`. Returns the 0-based line\r\n * index of the closing `}`, or -1 on failure.\r\n */\r\nfunction braceMatchForward(lines: string[], start: number, maxLine: number): number {\r\n let depth = 0;\r\n let foundOpen = false;\r\n\r\n for (let i = start; i <= maxLine; i++) {\r\n for (const ch of lines[i]) {\r\n if (ch === '{') { depth++; foundOpen = true; }\r\n if (ch === '}') {\r\n depth--;\r\n if (foundOpen && depth === 0) return i;\r\n }\r\n }\r\n }\r\n return -1;\r\n}\r\n"]}
|
|
@@ -44,6 +44,7 @@ exports.findTestClassInsertPosition = findTestClassInsertPosition;
|
|
|
44
44
|
const fs = __importStar(require("fs"));
|
|
45
45
|
const repairRequiredNameSpaces_1 = require("./repairRequiredNameSpaces");
|
|
46
46
|
const constants_1 = require("../../types/constants");
|
|
47
|
+
const removeFailedTestMethods_1 = require("../../utils/removeFailedTestMethods");
|
|
47
48
|
/**
|
|
48
49
|
* Post-process LLM-generated content for the "more UT" scenario.
|
|
49
50
|
*
|
|
@@ -102,7 +103,9 @@ function postGenMoreUTProcess(generatedContent, testFilePath, isXapCode) {
|
|
|
102
103
|
insertedRanges.push(helperResult.range);
|
|
103
104
|
}
|
|
104
105
|
// Step 7: Restore the original line-ending style
|
|
105
|
-
|
|
106
|
+
let testCode = resultLines.join('\n').replace(/\n/g, lineEnding);
|
|
107
|
+
// Step 8: Remove trailing whitespace from each line (trim_trailing_whitespace)
|
|
108
|
+
testCode = testCode.split(lineEnding).map(line => line.replace(/\s+$/, '')).join(lineEnding);
|
|
106
109
|
console.log(`Post generation (more UT) process completed, code length: ${testCode.length}`);
|
|
107
110
|
return { testCode, insertedRanges };
|
|
108
111
|
}
|
|
@@ -164,8 +167,24 @@ function insertTestMethods(resultLines, testMethods, baseIndent, originalLines,
|
|
|
164
167
|
return { lines: resultLines, range: null, linesInserted: 0, insertEnd: 0 };
|
|
165
168
|
}
|
|
166
169
|
const normalizedTestMethods = testMethods.replace(/\r\n/g, '\n');
|
|
167
|
-
const
|
|
168
|
-
const
|
|
170
|
+
const testMethodBlocks = extractTestMethodBlocks(normalizedTestMethods);
|
|
171
|
+
const existingTestMethodNames = collectTestMethodNames(resultLines);
|
|
172
|
+
const keptBlocks = testMethodBlocks.filter(block => {
|
|
173
|
+
if (!block.methodName)
|
|
174
|
+
return true;
|
|
175
|
+
if (existingTestMethodNames.has(block.methodName)) {
|
|
176
|
+
console.log(`Skip duplicate test method: ${block.methodName}`);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
existingTestMethodNames.add(block.methodName);
|
|
180
|
+
return true;
|
|
181
|
+
});
|
|
182
|
+
if (keptBlocks.length === 0) {
|
|
183
|
+
console.log('All generated test methods already exist in the original file, skipping insertion.');
|
|
184
|
+
return { lines: resultLines, range: null, linesInserted: 0, insertEnd: 0 };
|
|
185
|
+
}
|
|
186
|
+
const indentedBlocks = keptBlocks.map(block => applyIndentation(block.content, baseIndent));
|
|
187
|
+
const testMethodLines = indentedBlocks.join('\n\n').split('\n');
|
|
169
188
|
// Find the insertion point in the *original* file (before any offset)
|
|
170
189
|
let calculatedInsertLine = findLastTestMethodEndLine(originalLines);
|
|
171
190
|
if (calculatedInsertLine === 0) {
|
|
@@ -195,7 +214,39 @@ function insertHelperCode(resultLines, helperCode, baseIndent, originalLines, of
|
|
|
195
214
|
return { lines: resultLines, range: null, linesInserted: 0 };
|
|
196
215
|
}
|
|
197
216
|
const normalizedHelperCode = helperCode.replace(/\r\n/g, '\n');
|
|
198
|
-
const
|
|
217
|
+
const helperBlocks = splitTopLevelBlocks(normalizedHelperCode);
|
|
218
|
+
const existingMethodNames = collectAllMethodNames(resultLines);
|
|
219
|
+
const existingNormalizedContent = normalizeCodeForComparison(resultLines.join('\n'));
|
|
220
|
+
const seenNormalizedFragments = new Set();
|
|
221
|
+
const keptBlocks = [];
|
|
222
|
+
for (const block of helperBlocks) {
|
|
223
|
+
const methodName = getMethodNameFromBlock(block);
|
|
224
|
+
if (methodName) {
|
|
225
|
+
if (existingMethodNames.has(methodName)) {
|
|
226
|
+
console.log(`Skip duplicate helper method: ${methodName}`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
existingMethodNames.add(methodName);
|
|
230
|
+
keptBlocks.push(block);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (containsNormalizedFragment(existingNormalizedContent, block)) {
|
|
234
|
+
console.log('Skip duplicate helper non-method block by normalized-content check.');
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const normalizedBlock = normalizeCodeForComparison(block);
|
|
238
|
+
if (seenNormalizedFragments.has(normalizedBlock)) {
|
|
239
|
+
console.log('Skip duplicate helper non-method block within generated HELPER_CODE.');
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
seenNormalizedFragments.add(normalizedBlock);
|
|
243
|
+
keptBlocks.push(block);
|
|
244
|
+
}
|
|
245
|
+
if (keptBlocks.length === 0) {
|
|
246
|
+
console.log('All helper code already exists in the original file, skipping insertion.');
|
|
247
|
+
return { lines: resultLines, range: null, linesInserted: 0 };
|
|
248
|
+
}
|
|
249
|
+
const indentedHelperCode = keptBlocks.map(block => applyIndentation(block, baseIndent)).join('\n\n');
|
|
199
250
|
const helperLines = indentedHelperCode.split('\n');
|
|
200
251
|
// Determine insertion point: right after test methods, or fallback
|
|
201
252
|
let insertHelperAt;
|
|
@@ -511,4 +562,157 @@ function findTestClassInsertPosition(lines) {
|
|
|
511
562
|
}
|
|
512
563
|
return 0;
|
|
513
564
|
}
|
|
565
|
+
function extractTestMethodBlocks(content) {
|
|
566
|
+
const lines = content.split('\n');
|
|
567
|
+
const testMethodPatterns = [
|
|
568
|
+
/\[TestMethod\]/i,
|
|
569
|
+
/\[Test\]/i,
|
|
570
|
+
/\[Fact\]/i,
|
|
571
|
+
/\[Theory\]/i
|
|
572
|
+
];
|
|
573
|
+
const visitedStarts = new Set();
|
|
574
|
+
const blocks = [];
|
|
575
|
+
for (let i = 0; i < lines.length; i++) {
|
|
576
|
+
const line = lines[i].trim();
|
|
577
|
+
const isTestAttr = testMethodPatterns.some(pattern => pattern.test(line));
|
|
578
|
+
if (!isTestAttr)
|
|
579
|
+
continue;
|
|
580
|
+
const range = (0, removeFailedTestMethods_1.findTestMethodRangeByBrace)(lines, i);
|
|
581
|
+
if (!range || visitedStarts.has(range.start))
|
|
582
|
+
continue;
|
|
583
|
+
visitedStarts.add(range.start);
|
|
584
|
+
const blockLines = lines.slice(range.start, range.end + 1);
|
|
585
|
+
let methodName = null;
|
|
586
|
+
for (const blockLine of blockLines) {
|
|
587
|
+
const trimmed = blockLine.trim();
|
|
588
|
+
if (!trimmed || trimmed.startsWith('['))
|
|
589
|
+
continue;
|
|
590
|
+
methodName = (0, removeFailedTestMethods_1.extractMethodName)(trimmed) || null;
|
|
591
|
+
if (methodName)
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
blocks.push({ methodName, content: blockLines.join('\n') });
|
|
595
|
+
}
|
|
596
|
+
if (blocks.length > 0) {
|
|
597
|
+
return blocks;
|
|
598
|
+
}
|
|
599
|
+
return [{ methodName: null, content }];
|
|
600
|
+
}
|
|
601
|
+
function collectTestMethodNames(lines) {
|
|
602
|
+
const names = new Set();
|
|
603
|
+
const testMethodPatterns = [
|
|
604
|
+
/\[TestMethod\]/i,
|
|
605
|
+
/\[Test\]/i,
|
|
606
|
+
/\[Fact\]/i,
|
|
607
|
+
/\[Theory\]/i
|
|
608
|
+
];
|
|
609
|
+
for (let i = 0; i < lines.length; i++) {
|
|
610
|
+
const line = lines[i].trim();
|
|
611
|
+
const isTestAttr = testMethodPatterns.some(pattern => pattern.test(line));
|
|
612
|
+
if (!isTestAttr)
|
|
613
|
+
continue;
|
|
614
|
+
const range = (0, removeFailedTestMethods_1.findTestMethodRangeByBrace)(lines, i);
|
|
615
|
+
if (!range)
|
|
616
|
+
continue;
|
|
617
|
+
for (let j = range.start; j <= range.end; j++) {
|
|
618
|
+
const trimmed = lines[j].trim();
|
|
619
|
+
if (!trimmed || trimmed.startsWith('['))
|
|
620
|
+
continue;
|
|
621
|
+
const name = (0, removeFailedTestMethods_1.extractMethodName)(trimmed);
|
|
622
|
+
if (name) {
|
|
623
|
+
names.add(name);
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return names;
|
|
629
|
+
}
|
|
630
|
+
function collectAllMethodNames(lines) {
|
|
631
|
+
const names = new Set();
|
|
632
|
+
for (const line of lines) {
|
|
633
|
+
const trimmed = line.trim();
|
|
634
|
+
if (!isLikelyMethodSignature(trimmed))
|
|
635
|
+
continue;
|
|
636
|
+
const name = (0, removeFailedTestMethods_1.extractMethodName)(trimmed);
|
|
637
|
+
if (name)
|
|
638
|
+
names.add(name);
|
|
639
|
+
}
|
|
640
|
+
return names;
|
|
641
|
+
}
|
|
642
|
+
function splitTopLevelBlocks(content) {
|
|
643
|
+
const lines = content.split('\n');
|
|
644
|
+
const blocks = [];
|
|
645
|
+
let current = [];
|
|
646
|
+
let braceDepth = 0;
|
|
647
|
+
const flushCurrent = () => {
|
|
648
|
+
if (current.length === 0)
|
|
649
|
+
return;
|
|
650
|
+
const block = current.join('\n').trim();
|
|
651
|
+
if (block)
|
|
652
|
+
blocks.push(block);
|
|
653
|
+
current = [];
|
|
654
|
+
};
|
|
655
|
+
for (const line of lines) {
|
|
656
|
+
const trimmed = line.trim();
|
|
657
|
+
if (trimmed === '' && current.length === 0) {
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
current.push(line);
|
|
661
|
+
braceDepth += countChar(line, '{');
|
|
662
|
+
braceDepth -= countChar(line, '}');
|
|
663
|
+
if (braceDepth <= 0 && current.length > 0) {
|
|
664
|
+
flushCurrent();
|
|
665
|
+
braceDepth = 0;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
flushCurrent();
|
|
669
|
+
return blocks;
|
|
670
|
+
}
|
|
671
|
+
function getMethodNameFromBlock(block) {
|
|
672
|
+
const lines = block.split('\n');
|
|
673
|
+
for (const line of lines) {
|
|
674
|
+
const trimmed = line.trim();
|
|
675
|
+
if (!trimmed || trimmed.startsWith('['))
|
|
676
|
+
continue;
|
|
677
|
+
if (!isLikelyMethodSignature(trimmed))
|
|
678
|
+
return null;
|
|
679
|
+
const name = (0, removeFailedTestMethods_1.extractMethodName)(trimmed);
|
|
680
|
+
return name || null;
|
|
681
|
+
}
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
684
|
+
function isLikelyMethodSignature(line) {
|
|
685
|
+
if (!/^(public|private|protected|internal)\b/.test(line))
|
|
686
|
+
return false;
|
|
687
|
+
if (/\b(class|interface|enum|struct|record)\b/.test(line))
|
|
688
|
+
return false;
|
|
689
|
+
if (!line.includes('(') || !line.includes(')'))
|
|
690
|
+
return false;
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
function normalizeCodeForComparison(code) {
|
|
694
|
+
return code
|
|
695
|
+
.replace(/\r\n/g, '\n')
|
|
696
|
+
.split('\n')
|
|
697
|
+
.map(line => line.trim())
|
|
698
|
+
.filter(line => line !== '')
|
|
699
|
+
.join('\n')
|
|
700
|
+
.replace(/\s+/g, ' ')
|
|
701
|
+
.trim();
|
|
702
|
+
}
|
|
703
|
+
function containsNormalizedFragment(existingNormalizedContent, fragment) {
|
|
704
|
+
const normalizedFragment = normalizeCodeForComparison(fragment);
|
|
705
|
+
if (!normalizedFragment) {
|
|
706
|
+
return true;
|
|
707
|
+
}
|
|
708
|
+
return existingNormalizedContent.includes(normalizedFragment);
|
|
709
|
+
}
|
|
710
|
+
function countChar(value, target) {
|
|
711
|
+
let count = 0;
|
|
712
|
+
for (const ch of value) {
|
|
713
|
+
if (ch === target)
|
|
714
|
+
count++;
|
|
715
|
+
}
|
|
716
|
+
return count;
|
|
717
|
+
}
|
|
514
718
|
//# sourceMappingURL=postGenMoreUTProcess.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postGenMoreUTProcess.js","sourceRoot":"","sources":["../../../src/gen/postGen/postGenMoreUTProcess.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,oDA4DC;AA4LD,4CAEC;AAMD,wEASC;AASD,0DAMC;AASD,wDA0CC;AAMD,4CA6BC;AAMD,8DA+FC;AAMD,kEAsCC;AAniBD,uCAAyB;AAEzB,yEAAyH;AACzH,qDAAgE;AAehE;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,oBAAoB,CAChC,gBAAwB,EACxB,YAAoB,EACpB,SAAkB;IAElB,4CAA4C;IAC5C,MAAM,MAAM,GAAG,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAE5D,oDAAoD;IACpD,MAAM,gBAAgB,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACtD,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAErD,6DAA6D;IAC7D,MAAM,UAAU,GAAG,sBAAsB,CAAC,aAAa,CAAC,CAAC;IAEzD,MAAM,cAAc,GAAuB,EAAE,CAAC;IAC9C,IAAI,WAAW,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC;IACrC,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,2CAA2C;IAC3C,MAAM,WAAW,GAAG,qBAAqB,CACrC,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAC3E,CAAC;IACF,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC;IAChC,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,IAAI,WAAW,CAAC,aAAa,CAAC;IAEpC,kCAAkC;IAClC,IAAI,mBAAmB,GAAG,CAAC,CAAC;IAC5B,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;IACxG,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC;IACrC,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;QACzB,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC5C,mBAAmB,GAAG,gBAAgB,CAAC,SAAS,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,gBAAgB,CAAC,aAAa,CAAC;IAEzC,0DAA0D;IAC1D,MAAM,YAAY,GAAG,gBAAgB,CACjC,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAmB,CAClF,CAAC;IACF,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC;IACjC,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;QACrB,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,iDAAiD;IACjD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,6DAA6D,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAE5F,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AACxC,CAAC;AAED,8EAA8E;AAC9E,+EAA+E;AAC/E,oEAAoE;AACpE,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,qBAAqB,CAC1B,WAAqB,EACrB,eAAmC,EACnC,SAAkB,EAClB,WAA+B,EAC/B,UAA8B,EAC9B,MAAc;IAEd,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;IACjE,CAAC;IAED,8DAA8D;IAC9D,IAAI,kBAAkB,GAAG,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvF,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,CAAC,GAAG,8CAAmB,CAAC,CAAC;QAC3C,wEAAwE;QACxE,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YACrG,SAAS,CAAC,IAAI,CAAC,mCAAuB,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,kBAAkB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,kBAAkB,KAAK,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;IACtG,CAAC;IAED,2EAA2E;IAC3E,MAAM,cAAc,GAAG,8BAA8B,CAAC,WAAW,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,kBAAkB;SACnC,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;SAClC,MAAM,CAAC,IAAI,CAAC,EAAE;QACX,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,IAAI,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAChE,OAAO,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,qCAAqC;IAChF,CAAC,CAAC,CAAC;IAEP,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAC;QAC5F,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;IACjE,CAAC;IAED,sDAAsD;IACtD,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAA,oDAAyB,EAAC,WAAW,CAAC,CAAC;IACnG,MAAM,aAAa,GAAG,gBAAgB,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEhF,MAAM,WAAW,GAAG,aAAa,GAAG,MAAM,CAAC;IAC3C,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC;IAElD,MAAM,cAAc,GAAG,WAAW,GAAG,CAAC,CAAC;IACvC,MAAM,YAAY,GAAG,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,YAAY,UAAU,CAAC,MAAM,yBAAyB,WAAW,aAAa,cAAc,KAAK,YAAY,GAAG,CAAC,CAAC;IAE9H,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AAC3G,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CACtB,WAAqB,EACrB,WAA+B,EAC/B,UAAkB,EAClB,aAAuB,EACvB,MAAc;IAEd,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC/E,CAAC;IAED,MAAM,qBAAqB,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC;IAChF,MAAM,eAAe,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAExD,sEAAsE;IACtE,IAAI,oBAAoB,GAAG,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACpE,IAAI,oBAAoB,KAAK,CAAC,EAAE,CAAC;QAC7B,oBAAoB,GAAG,2BAA2B,CAAC,aAAa,CAAC,CAAC;QAClE,IAAI,oBAAoB,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACrE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QAC/E,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,cAAc,GAAG,oBAAoB,GAAG,CAAC,GAAG,MAAM,CAAC;IAEzD,wCAAwC;IACxC,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,eAAe,CAAC,CAAC;IAE9D,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,oBAAoB;IACtE,MAAM,eAAe,GAAG,cAAc,GAAG,CAAC,CAAC;IAC3C,MAAM,aAAa,GAAG,cAAc,GAAG,aAAa,CAAC;IACrD,MAAM,SAAS,GAAG,cAAc,GAAG,aAAa,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,YAAY,aAAa,0CAA0C,cAAc,aAAa,eAAe,KAAK,aAAa,GAAG,CAAC,CAAC;IAEhJ,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACrG,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CACrB,WAAqB,EACrB,UAA8B,EAC9B,UAAkB,EAClB,aAAuB,EACvB,MAAc,EACd,mBAA2B;IAE3B,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;IACjE,CAAC;IAED,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/D,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;IAC9E,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEnD,mEAAmE;IACnE,IAAI,cAAsB,CAAC;IAC3B,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;QAC1B,cAAc,GAAG,mBAAmB,CAAC;IACzC,CAAC;SAAM,CAAC;QACJ,IAAI,gBAAgB,GAAG,yBAAyB,CAAC,aAAa,CAAC,CAAC;QAChE,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC;YACzB,gBAAgB,GAAG,2BAA2B,CAAC,aAAa,CAAC,CAAC;QAClE,CAAC;QACD,cAAc,GAAG,gBAAgB,GAAG,CAAC,GAAG,MAAM,CAAC;IACnD,CAAC;IAED,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC;IAEtD,MAAM,eAAe,GAAG,cAAc,GAAG,CAAC,CAAC;IAC3C,MAAM,aAAa,GAAG,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,CAAC,MAAM,+BAA+B,cAAc,aAAa,eAAe,KAAK,aAAa,GAAG,CAAC,CAAC;IAE1I,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,EAAE,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;AAC9G,CAAC;AAED,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,2BAA2B,CAAC,OAAe;IAChD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACpC,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACxE,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvE,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpE,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACzE,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,OAAe;IAC5C,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,SAAgB,8BAA8B,CAAC,KAAe;IAC1D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,UAAU,EAAE,CAAC;YACb,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;IACD,OAAO,cAAc,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,uBAAuB,CAAC,IAAY;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CAAC,KAAe;IAClD,MAAM,kBAAkB,GAAG;QACvB,iBAAiB;QACjB,WAAW;QACX,WAAW;QACX,aAAa;KAChB,CAAC;IAEF,iDAAiD;IACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACnC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,CAAC;QACL,CAAC;IACL,CAAC;IAED,6DAA6D;IAC7D,MAAM,YAAY,GAAG,wCAAwC,CAAC;IAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACzB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;wBAC1B,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;4BAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;4BACvC,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;4BACpB,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,MAAM;gBACV,CAAC;YACL,CAAC;YACD,MAAM;QACV,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC,CAAC,oBAAoB;AAC3C,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,IAAY,EAAE,UAAkB;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,sCAAsC;IACtC,IAAI,SAAS,GAAG,QAAQ,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;YACrB,SAAS,GAAG,MAAM,CAAC;QACvB,CAAC;IACL,CAAC;IACD,IAAI,SAAS,KAAK,QAAQ;QAAE,SAAS,GAAG,CAAC,CAAC;IAE1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,cAAc,GAAG,aAAa,GAAG,SAAS,CAAC;YACjD,MAAM,SAAS,GAAG,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAC1D,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,SAAgB,yBAAyB,CAAC,KAAe;IACrD,MAAM,kBAAkB,GAAG;QACvB,iBAAiB;QACjB,WAAW;QACX,WAAW;QACX,aAAa;KAChB,CAAC;IAEF,IAAI,wBAAwB,GAAG,CAAC,CAAC,CAAC;IAElC,oDAAoD;IACpD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,wBAAwB,GAAG,CAAC,CAAC;gBAC7B,MAAM;YACV,CAAC;QACL,CAAC;QACD,IAAI,wBAAwB,KAAK,CAAC,CAAC;YAAE,MAAM;IAC/C,CAAC;IAED,IAAI,wBAAwB,KAAK,CAAC,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,CAAC;IACb,CAAC;IAED,yEAAyE;IACzE,6EAA6E;IAC7E,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,wBAAwB,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAC7B,IAAI,aAAa,GAAG,KAAK,CAAC;QAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAEpD,yCAAyC;YACzC,IAAI,kBAAkB,EAAE,CAAC;gBACrB,IAAI,EAAE,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;oBAC7B,kBAAkB,GAAG,KAAK,CAAC;oBAC3B,CAAC,EAAE,CAAC;gBACR,CAAC;gBACD,SAAS;YACb,CAAC;YAED,+DAA+D;YAC/D,IAAI,gBAAgB,EAAE,CAAC;gBACnB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;oBACb,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;wBAAC,CAAC,EAAE,CAAC;oBAAC,CAAC,CAAC,gBAAgB;yBACtC,CAAC;wBAAC,gBAAgB,GAAG,KAAK,CAAC;oBAAC,CAAC;gBACtC,CAAC;gBACD,SAAS;YACb,CAAC;YAED,0CAA0C;YAC1C,IAAI,QAAQ,EAAE,CAAC;gBACX,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;oBAAC,CAAC,EAAE,CAAC;gBAAC,CAAC;qBACpB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;oBAAC,QAAQ,GAAG,KAAK,CAAC;gBAAC,CAAC;gBAC1C,SAAS;YACb,CAAC;YAED,wCAAwC;YACxC,IAAI,aAAa,EAAE,CAAC;gBAChB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;oBAAC,CAAC,EAAE,CAAC;gBAAC,CAAC;qBACpB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;oBAAC,aAAa,GAAG,KAAK,CAAC;gBAAC,CAAC;gBAChD,SAAS;YACb,CAAC;YAED,mDAAmD;YACnD,IAAI,EAAE,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBAAC,MAAM;YAAC,CAAC,CAAC,yCAAyC;YACpF,IAAI,EAAE,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBAAC,kBAAkB,GAAG,IAAI,CAAC;gBAAC,CAAC,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC7E,IAAI,EAAE,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBAAC,gBAAgB,GAAG,IAAI,CAAC;gBAAC,CAAC,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC3E,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBAAC,QAAQ,GAAG,IAAI,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC9C,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;gBAAC,aAAa,GAAG,IAAI,CAAC;gBAAC,SAAS;YAAC,CAAC;YAEpD,8BAA8B;YAC9B,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACb,UAAU,EAAE,CAAC;gBACb,iBAAiB,GAAG,IAAI,CAAC;YAC7B,CAAC;iBAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACpB,UAAU,EAAE,CAAC;gBACb,IAAI,iBAAiB,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;oBACxC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,oDAAoD;gBACtE,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,CAAC,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CAAC,KAAe;IACvD,MAAM,iBAAiB,GAAG,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,kDAAkD,CAAC;IAExE,IAAI,uBAAuB,GAAG,CAAC,CAAC,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,uBAAuB,GAAG,CAAC,CAAC;gBAC5B,MAAM;YACV,CAAC;QACL,CAAC;QACD,IAAI,uBAAuB,KAAK,CAAC,CAAC;YAAE,MAAM;IAC9C,CAAC;IAED,MAAM,gBAAgB,GAAG,uBAAuB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,IAAI,qBAAqB,GAAG,CAAC,CAAC,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,gBAAgB,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,KAAK,CAAC,CAAC,IAAI,wCAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACrH,qBAAqB,GAAG,CAAC,CAAC;YAC1B,MAAM;QACV,CAAC;IACL,CAAC;IAED,IAAI,qBAAqB,KAAK,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC;IACb,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,qBAAqB,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,+CAA+C;QACjE,CAAC;IACL,CAAC;IAED,OAAO,CAAC,CAAC;AACb,CAAC","sourcesContent":["import * as fs from 'fs';\r\n\r\nimport { detectUsingInsertPosition, repairXapRequiredNameSpaces, XAP_REQUIRED_USINGS } from \"./repairRequiredNameSpaces\";\r\nimport { XapBondRelatedNamespace } from \"../../types/constants\";\r\n\r\n/** Result of the post-generation process for additional unit tests */\r\ninterface MoreUTResult {\r\n testCode: string;\r\n insertedRanges: [number, number][];\r\n}\r\n\r\n/** Parsed sections from the LLM-generated content */\r\ninterface ParsedMoreUtContent {\r\n usingStatements: string;\r\n testMethods: string;\r\n helperCode: string;\r\n}\r\n\r\n/**\r\n * Post-process LLM-generated content for the \"more UT\" scenario.\r\n *\r\n * Unlike `postGenProcess` which handles brand-new test files, this function\r\n * merges newly generated test methods, using statements and helper code into\r\n * an **existing** test file. It:\r\n * 1. Parses the structured LLM response (USING_STATEMENTS / TEST_METHODS / HELPER_CODE sections).\r\n * 2. De-duplicates and inserts new `using` directives at the correct position.\r\n * 3. Inserts new test methods right after the last existing test method.\r\n * 4. Appends helper code immediately after the newly inserted test methods.\r\n * 5. Preserves the original line-ending style (CRLF / LF).\r\n *\r\n * @param generatedContent Raw LLM response containing fenced code sections.\r\n * @param testFilePath Absolute path to the existing test file on disk.\r\n * @param isXapCode Whether Xap-specific using directives should be injected.\r\n * @returns An object with the merged test code and the line ranges that were inserted,\r\n * or `undefined` if the generated content could not be parsed.\r\n */\r\nexport function postGenMoreUTProcess(\r\n generatedContent: string,\r\n testFilePath: string,\r\n isXapCode: boolean\r\n): MoreUTResult | undefined {\r\n // Step 1: Parse the structured LLM response\r\n const parsed = parseGeneratedMoreUtContent(generatedContent);\r\n if (!parsed) {\r\n return undefined;\r\n }\r\n\r\n const { usingStatements, testMethods, helperCode } = parsed;\r\n\r\n // Step 2: Read and normalise the original test file\r\n const originalTestCode = fs.readFileSync(testFilePath, 'utf-8');\r\n const lineEnding = detectLineEnding(originalTestCode);\r\n const normalizedOriginal = originalTestCode.replace(/\\r\\n/g, '\\n');\r\n const originalLines = normalizedOriginal.split('\\n');\r\n\r\n // Step 3: Detect the indentation convention used in the file\r\n const baseIndent = detectTestMethodIndent(originalLines);\r\n\r\n const insertedRanges: [number, number][] = [];\r\n let resultLines = [...originalLines];\r\n let offset = 0;\r\n\r\n // Step 4: Insert using statements (if any)\r\n const usingResult = insertUsingStatements(\r\n resultLines, usingStatements, isXapCode, testMethods, helperCode, offset\r\n );\r\n resultLines = usingResult.lines;\r\n if (usingResult.range) {\r\n insertedRanges.push(usingResult.range);\r\n }\r\n offset += usingResult.linesInserted;\r\n\r\n // Step 5: Insert new test methods\r\n let testMethodInsertEnd = 0;\r\n const testMethodResult = insertTestMethods(resultLines, testMethods, baseIndent, originalLines, offset);\r\n resultLines = testMethodResult.lines;\r\n if (testMethodResult.range) {\r\n insertedRanges.push(testMethodResult.range);\r\n testMethodInsertEnd = testMethodResult.insertEnd;\r\n }\r\n offset += testMethodResult.linesInserted;\r\n\r\n // Step 6: Insert helper code right after the test methods\r\n const helperResult = insertHelperCode(\r\n resultLines, helperCode, baseIndent, originalLines, offset, testMethodInsertEnd\r\n );\r\n resultLines = helperResult.lines;\r\n if (helperResult.range) {\r\n insertedRanges.push(helperResult.range);\r\n }\r\n\r\n // Step 7: Restore the original line-ending style\r\n const testCode = resultLines.join('\\n').replace(/\\n/g, lineEnding);\r\n console.log(`Post generation (more UT) process completed, code length: ${testCode.length}`);\r\n\r\n return { testCode, insertedRanges };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Section inserters – each returns the mutated line array, the inserted range\r\n// and the number of lines added so callers can maintain an offset.\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Insert new `using` directives that don't already exist in the file.\r\n * Also injects Xap-specific usings when `isXapCode` is true.\r\n */\r\nfunction insertUsingStatements(\r\n resultLines: string[],\r\n usingStatements: string | undefined,\r\n isXapCode: boolean,\r\n testMethods: string | undefined,\r\n helperCode: string | undefined,\r\n offset: number\r\n): { lines: string[]; range: [number, number] | null; linesInserted: number } {\r\n if (!usingStatements?.trim() && !isXapCode) {\r\n return { lines: resultLines, range: null, linesInserted: 0 };\r\n }\r\n\r\n // Collect all using statements (user-provided + Xap-specific)\r\n let allUsingStatements = usingStatements ? usingStatements.replace(/\\r\\n/g, '\\n') : '';\r\n\r\n if (isXapCode) {\r\n const xapUsings = [...XAP_REQUIRED_USINGS];\r\n // Only add XapBondRelatedNamespace if generated code references XapBlob\r\n if ((testMethods && testMethods.includes('XapBlob')) || (helperCode && helperCode.includes('XapBlob'))) {\r\n xapUsings.push(XapBondRelatedNamespace);\r\n }\r\n const xapUsingsStr = xapUsings.join('\\n');\r\n allUsingStatements = allUsingStatements ? `${allUsingStatements}\\n${xapUsingsStr}` : xapUsingsStr;\r\n }\r\n\r\n // De-duplicate against the original file AND within the merged list itself\r\n const existingUsings = extractExistingUsingStatements(resultLines);\r\n const newUsingLines = allUsingStatements\r\n .split('\\n')\r\n .filter(line => line.trim() !== '')\r\n .filter(line => {\r\n const normalized = normalizeUsingStatement(line);\r\n if (!normalized || existingUsings.has(normalized)) return false;\r\n return existingUsings.add(normalized); // Set.add() returns the Set (truthy)\r\n });\r\n\r\n if (newUsingLines.length === 0) {\r\n console.log('All using statements already exist in the original file, skipping insertion.');\r\n return { lines: resultLines, range: null, linesInserted: 0 };\r\n }\r\n\r\n // Determine where and with what indentation to insert\r\n const { insertIndex: insertUsingAt, indent: usingIndent } = detectUsingInsertPosition(resultLines);\r\n const indentedUsing = applyIndentation(newUsingLines.join('\\n'), usingIndent);\r\n const usingLines = indentedUsing.split('\\n').filter(line => line.trim() !== '');\r\n\r\n const insertIndex = insertUsingAt + offset;\r\n resultLines.splice(insertIndex, 0, ...usingLines);\r\n\r\n const usingStartLine = insertIndex + 1;\r\n const usingEndLine = insertIndex + usingLines.length;\r\n console.log(`Inserted ${usingLines.length} using lines at index ${insertIndex}, range: [${usingStartLine}, ${usingEndLine}]`);\r\n\r\n return { lines: resultLines, range: [usingStartLine, usingEndLine], linesInserted: usingLines.length };\r\n}\r\n\r\n/**\r\n * Insert new test methods after the last existing test method in the file.\r\n * Falls back to inserting after the test-class opening brace when no methods exist.\r\n */\r\nfunction insertTestMethods(\r\n resultLines: string[],\r\n testMethods: string | undefined,\r\n baseIndent: string,\r\n originalLines: string[],\r\n offset: number\r\n): { lines: string[]; range: [number, number] | null; linesInserted: number; insertEnd: number } {\r\n if (!testMethods?.trim()) {\r\n return { lines: resultLines, range: null, linesInserted: 0, insertEnd: 0 };\r\n }\r\n\r\n const normalizedTestMethods = testMethods.replace(/\\r\\n/g, '\\n');\r\n const indentedTestMethods = applyIndentation(normalizedTestMethods, baseIndent);\r\n const testMethodLines = indentedTestMethods.split('\\n');\r\n\r\n // Find the insertion point in the *original* file (before any offset)\r\n let calculatedInsertLine = findLastTestMethodEndLine(originalLines);\r\n if (calculatedInsertLine === 0) {\r\n calculatedInsertLine = findTestClassInsertPosition(originalLines);\r\n if (calculatedInsertLine === 0) {\r\n console.error('Failed to find insert position for new test methods');\r\n return { lines: resultLines, range: null, linesInserted: 0, insertEnd: 0 };\r\n }\r\n console.log('No existing test methods found, inserting after test class opening brace');\r\n }\r\n\r\n const insertMethodAt = calculatedInsertLine - 1 + offset;\r\n\r\n // Prepend an empty line for readability\r\n resultLines.splice(insertMethodAt, 0, '', ...testMethodLines);\r\n\r\n const linesInserted = testMethodLines.length + 1; // +1 for empty line\r\n const methodStartLine = insertMethodAt + 1;\r\n const methodEndLine = insertMethodAt + linesInserted;\r\n const insertEnd = insertMethodAt + linesInserted;\r\n console.log(`Inserted ${linesInserted} lines (including empty line) at index ${insertMethodAt}, range: [${methodStartLine}, ${methodEndLine}]`);\r\n\r\n return { lines: resultLines, range: [methodStartLine, methodEndLine], linesInserted, insertEnd };\r\n}\r\n\r\n/**\r\n * Insert helper / utility code immediately after the newly inserted test methods.\r\n * Falls back to appending after the last test method if no new methods were inserted.\r\n */\r\nfunction insertHelperCode(\r\n resultLines: string[],\r\n helperCode: string | undefined,\r\n baseIndent: string,\r\n originalLines: string[],\r\n offset: number,\r\n testMethodInsertEnd: number\r\n): { lines: string[]; range: [number, number] | null; linesInserted: number } {\r\n if (!helperCode?.trim()) {\r\n return { lines: resultLines, range: null, linesInserted: 0 };\r\n }\r\n\r\n const normalizedHelperCode = helperCode.replace(/\\r\\n/g, '\\n');\r\n const indentedHelperCode = applyIndentation(normalizedHelperCode, baseIndent);\r\n const helperLines = indentedHelperCode.split('\\n');\r\n\r\n // Determine insertion point: right after test methods, or fallback\r\n let insertHelperAt: number;\r\n if (testMethodInsertEnd > 0) {\r\n insertHelperAt = testMethodInsertEnd;\r\n } else {\r\n let helperInsertLine = findLastTestMethodEndLine(originalLines);\r\n if (helperInsertLine === 0) {\r\n helperInsertLine = findTestClassInsertPosition(originalLines);\r\n }\r\n insertHelperAt = helperInsertLine - 1 + offset;\r\n }\r\n\r\n resultLines.splice(insertHelperAt, 0, ...helperLines);\r\n\r\n const helperStartLine = insertHelperAt + 1;\r\n const helperEndLine = insertHelperAt + helperLines.length;\r\n console.log(`Inserted ${helperLines.length} helper code lines at index ${insertHelperAt}, range: [${helperStartLine}, ${helperEndLine}]`);\r\n\r\n return { lines: resultLines, range: [helperStartLine, helperEndLine], linesInserted: helperLines.length };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Parsing & detection helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Parse the structured LLM response into three fenced-code sections:\r\n * `USING_STATEMENTS`, `TEST_METHODS` and `HELPER_CODE`.\r\n *\r\n * Only `TEST_METHODS` is mandatory – the others may be empty.\r\n */\r\nfunction parseGeneratedMoreUtContent(content: string): ParsedMoreUtContent | undefined {\r\n if (!content || content.trim() === '') {\r\n return undefined;\r\n }\r\n\r\n const usingMatch = content.match(/```USING_STATEMENTS\\s*([\\s\\S]*?)```/);\r\n const usingStatements = usingMatch ? usingMatch[1].trim() : '';\r\n\r\n const testMethodsMatch = content.match(/```TEST_METHODS\\s*([\\s\\S]*?)```/);\r\n const testMethods = testMethodsMatch ? testMethodsMatch[1].trim() : '';\r\n\r\n const helperCodeMatch = content.match(/```HELPER_CODE\\s*([\\s\\S]*?)```/);\r\n const helperCode = helperCodeMatch ? helperCodeMatch[1].trim() : '';\r\n\r\n if (!testMethods) {\r\n console.error('Failed to parse generated content: missing TEST_METHODS');\r\n return undefined;\r\n }\r\n\r\n return { usingStatements, testMethods, helperCode };\r\n}\r\n\r\n/**\r\n * Detect the line-ending convention used in the file.\r\n * @returns `'\\r\\n'` for Windows (CRLF) or `'\\n'` for Unix (LF).\r\n */\r\nexport function detectLineEnding(content: string): string {\r\n return content.includes('\\r\\n') ? '\\r\\n' : '\\n';\r\n}\r\n\r\n/**\r\n * Collect all `using` directives already present in the file.\r\n * @returns A `Set` of normalised using strings for O(1) de-duplication.\r\n */\r\nexport function extractExistingUsingStatements(lines: string[]): Set<string> {\r\n const existingUsings = new Set<string>();\r\n for (const line of lines) {\r\n const normalized = normalizeUsingStatement(line);\r\n if (normalized) {\r\n existingUsings.add(normalized);\r\n }\r\n }\r\n return existingUsings;\r\n}\r\n\r\n/**\r\n * Normalise a `using` directive for comparison.\r\n * Strips whitespace and trailing semicolons so that\r\n * `\" using System.Linq ; \"` and `\"using System.Linq\"` match.\r\n *\r\n * @returns `null` when the line is not a using directive.\r\n */\r\nexport function normalizeUsingStatement(line: string): string | null {\r\n const trimmed = line.trim();\r\n if (!trimmed.startsWith('using ') || trimmed.includes('(')) {\r\n return null;\r\n }\r\n return trimmed.replace(/;?\\s*$/, '').replace(/\\s+/g, ' ');\r\n}\r\n\r\n/**\r\n * Detect the indentation level of test methods in the file\r\n * by looking for `[TestMethod]`, `[Test]`, `[Fact]` or `[Theory]` attributes.\r\n *\r\n * Falls back to the first non-empty line inside a class body,\r\n * or 8 spaces if nothing useful is found.\r\n */\r\nexport function detectTestMethodIndent(lines: string[]): string {\r\n const testMethodPatterns = [\r\n /\\[TestMethod\\]/i,\r\n /\\[Test\\]/i,\r\n /\\[Fact\\]/i,\r\n /\\[Theory\\]/i\r\n ];\r\n\r\n // Try to match an existing test-method attribute\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n for (const pattern of testMethodPatterns) {\r\n if (pattern.test(line)) {\r\n const match = line.match(/^(\\s*)/);\r\n return match ? match[1] : '';\r\n }\r\n }\r\n }\r\n\r\n // Fallback: use the first non-empty line inside a class body\r\n const classPattern = /^\\s*(public\\s+)?(partial\\s+)?class\\s+/i;\r\n for (let i = 0; i < lines.length; i++) {\r\n if (classPattern.test(lines[i])) {\r\n for (let j = i; j < lines.length; j++) {\r\n if (lines[j].includes('{')) {\r\n for (let k = j + 1; k < lines.length; k++) {\r\n const nextLine = lines[k];\r\n if (nextLine.trim() !== '' && !nextLine.trim().startsWith('}')) {\r\n const match = nextLine.match(/^(\\s*)/);\r\n if (match && match[1].length > 0) {\r\n return match[1];\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n\r\n return ' '; // default: 8 spaces\r\n}\r\n\r\n/**\r\n * Re-indent a block of code so its minimum indentation matches `baseIndent`,\r\n * while preserving the *relative* indentation of nested lines.\r\n */\r\nexport function applyIndentation(code: string, baseIndent: string): string {\r\n const lines = code.split('\\n');\r\n const result: string[] = [];\r\n\r\n // Detect existing minimum indentation\r\n let minIndent = Infinity;\r\n for (const line of lines) {\r\n if (line.trim() === '') continue;\r\n const match = line.match(/^(\\s*)/);\r\n const indent = match ? match[1].length : 0;\r\n if (indent < minIndent) {\r\n minIndent = indent;\r\n }\r\n }\r\n if (minIndent === Infinity) minIndent = 0;\r\n\r\n for (const line of lines) {\r\n if (line.trim() === '') {\r\n result.push('');\r\n } else {\r\n const match = line.match(/^(\\s*)/);\r\n const currentIndent = match ? match[1].length : 0;\r\n const relativeIndent = currentIndent - minIndent;\r\n const newIndent = baseIndent + ' '.repeat(relativeIndent);\r\n result.push(newIndent + line.trim());\r\n }\r\n }\r\n\r\n return result.join('\\n');\r\n}\r\n\r\n/**\r\n * Find the 1-based line number immediately after the last test method's\r\n * closing brace. Returns 0 when no test method is found.\r\n */\r\nexport function findLastTestMethodEndLine(lines: string[]): number {\r\n const testMethodPatterns = [\r\n /\\[TestMethod\\]/i,\r\n /\\[Test\\]/i,\r\n /\\[Fact\\]/i,\r\n /\\[Theory\\]/i\r\n ];\r\n\r\n let lastTestMethodStartIndex = -1;\r\n\r\n // Scan backwards for the last test-method attribute\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n const line = lines[i].trim();\r\n for (const pattern of testMethodPatterns) {\r\n if (pattern.test(line)) {\r\n lastTestMethodStartIndex = i;\r\n break;\r\n }\r\n }\r\n if (lastTestMethodStartIndex !== -1) break;\r\n }\r\n\r\n if (lastTestMethodStartIndex === -1) {\r\n return 0;\r\n }\r\n\r\n // Walk forward tracking brace depth to locate the matching closing brace\r\n // Skips braces inside strings, verbatim strings, char literals, and comments\r\n let braceCount = 0;\r\n let foundOpeningBrace = false;\r\n let inMultiLineComment = false;\r\n\r\n for (let i = lastTestMethodStartIndex; i < lines.length; i++) {\r\n const line = lines[i];\r\n let inString = false;\r\n let inVerbatimString = false;\r\n let inCharLiteral = false;\r\n\r\n for (let j = 0; j < line.length; j++) {\r\n const ch = line[j];\r\n const next = j + 1 < line.length ? line[j + 1] : '';\r\n\r\n // Inside multi-line comment: look for */\r\n if (inMultiLineComment) {\r\n if (ch === '*' && next === '/') {\r\n inMultiLineComment = false;\r\n j++;\r\n }\r\n continue;\r\n }\r\n\r\n // Inside verbatim string: only \"\" (escaped quote) or closing \"\r\n if (inVerbatimString) {\r\n if (ch === '\"') {\r\n if (next === '\"') { j++; } // escaped quote\r\n else { inVerbatimString = false; }\r\n }\r\n continue;\r\n }\r\n\r\n // Inside regular string: handle \\\" escape\r\n if (inString) {\r\n if (ch === '\\\\') { j++; }\r\n else if (ch === '\"') { inString = false; }\r\n continue;\r\n }\r\n\r\n // Inside char literal: handle \\' escape\r\n if (inCharLiteral) {\r\n if (ch === '\\\\') { j++; }\r\n else if (ch === '\\'') { inCharLiteral = false; }\r\n continue;\r\n }\r\n\r\n // Detect start of comments, strings, char literals\r\n if (ch === '/' && next === '/') { break; } // single-line comment: skip rest of line\r\n if (ch === '/' && next === '*') { inMultiLineComment = true; j++; continue; }\r\n if (ch === '@' && next === '\"') { inVerbatimString = true; j++; continue; }\r\n if (ch === '\"') { inString = true; continue; }\r\n if (ch === '\\'') { inCharLiteral = true; continue; }\r\n\r\n // Count braces in actual code\r\n if (ch === '{') {\r\n braceCount++;\r\n foundOpeningBrace = true;\r\n } else if (ch === '}') {\r\n braceCount--;\r\n if (foundOpeningBrace && braceCount === 0) {\r\n return i + 2; // i is 0-based → +1 for 1-based, +1 for *next* line\r\n }\r\n }\r\n }\r\n }\r\n\r\n return 0;\r\n}\r\n\r\n/**\r\n * Find the 1-based line number right after the test class's opening brace.\r\n * Used as a fallback when there are no existing test methods.\r\n */\r\nexport function findTestClassInsertPosition(lines: string[]): number {\r\n const testClassPatterns = [/\\[TestClass\\]/i, /\\[TestFixture\\]/i];\r\n const classPattern = /^\\s*(public\\s+)?(partial\\s+)?class\\s+\\w*Test\\w*/i;\r\n\r\n let testClassAttributeIndex = -1;\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n for (const pattern of testClassPatterns) {\r\n if (pattern.test(line)) {\r\n testClassAttributeIndex = i;\r\n break;\r\n }\r\n }\r\n if (testClassAttributeIndex !== -1) break;\r\n }\r\n\r\n const searchStartIndex = testClassAttributeIndex !== -1 ? testClassAttributeIndex : 0;\r\n let classDeclarationIndex = -1;\r\n\r\n for (let i = searchStartIndex; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (classPattern.test(line) || (testClassAttributeIndex !== -1 && /^\\s*(public\\s+)?(partial\\s+)?class\\s+/i.test(line))) {\r\n classDeclarationIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (classDeclarationIndex === -1) {\r\n return 0;\r\n }\r\n\r\n for (let i = classDeclarationIndex; i < lines.length; i++) {\r\n if (lines[i].indexOf('{') !== -1) {\r\n return i + 2; // 0-based → +1 for 1-based, +1 for *next* line\r\n }\r\n }\r\n\r\n return 0;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"postGenMoreUTProcess.js","sourceRoot":"","sources":["../../../src/gen/postGen/postGenMoreUTProcess.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\r\n\r\nimport { detectUsingInsertPosition, repairXapRequiredNameSpaces, XAP_REQUIRED_USINGS } from \"./repairRequiredNameSpaces\";\r\nimport { XapBondRelatedNamespace } from \"../../types/constants\";\r\nimport { extractMethodName, findTestMethodRangeByBrace } from '../../utils/removeFailedTestMethods';\r\n\r\n/** Result of the post-generation process for additional unit tests */\r\ninterface MoreUTResult {\r\n testCode: string;\r\n insertedRanges: [number, number][];\r\n}\r\n\r\n/** Parsed sections from the LLM-generated content */\r\ninterface ParsedMoreUtContent {\r\n usingStatements: string;\r\n testMethods: string;\r\n helperCode: string;\r\n}\r\n\r\n/**\r\n * Post-process LLM-generated content for the \"more UT\" scenario.\r\n *\r\n * Unlike `postGenProcess` which handles brand-new test files, this function\r\n * merges newly generated test methods, using statements and helper code into\r\n * an **existing** test file. It:\r\n * 1. Parses the structured LLM response (USING_STATEMENTS / TEST_METHODS / HELPER_CODE sections).\r\n * 2. De-duplicates and inserts new `using` directives at the correct position.\r\n * 3. Inserts new test methods right after the last existing test method.\r\n * 4. Appends helper code immediately after the newly inserted test methods.\r\n * 5. Preserves the original line-ending style (CRLF / LF).\r\n *\r\n * @param generatedContent Raw LLM response containing fenced code sections.\r\n * @param testFilePath Absolute path to the existing test file on disk.\r\n * @param isXapCode Whether Xap-specific using directives should be injected.\r\n * @returns An object with the merged test code and the line ranges that were inserted,\r\n * or `undefined` if the generated content could not be parsed.\r\n */\r\nexport function postGenMoreUTProcess(\r\n generatedContent: string,\r\n testFilePath: string,\r\n isXapCode: boolean\r\n): MoreUTResult | undefined {\r\n // Step 1: Parse the structured LLM response\r\n const parsed = parseGeneratedMoreUtContent(generatedContent);\r\n if (!parsed) {\r\n return undefined;\r\n }\r\n\r\n const { usingStatements, testMethods, helperCode } = parsed;\r\n\r\n // Step 2: Read and normalise the original test file\r\n const originalTestCode = fs.readFileSync(testFilePath, 'utf-8');\r\n const lineEnding = detectLineEnding(originalTestCode);\r\n const normalizedOriginal = originalTestCode.replace(/\\r\\n/g, '\\n');\r\n const originalLines = normalizedOriginal.split('\\n');\r\n\r\n // Step 3: Detect the indentation convention used in the file\r\n const baseIndent = detectTestMethodIndent(originalLines);\r\n\r\n const insertedRanges: [number, number][] = [];\r\n let resultLines = [...originalLines];\r\n let offset = 0;\r\n\r\n // Step 4: Insert using statements (if any)\r\n const usingResult = insertUsingStatements(\r\n resultLines, usingStatements, isXapCode, testMethods, helperCode, offset\r\n );\r\n resultLines = usingResult.lines;\r\n if (usingResult.range) {\r\n insertedRanges.push(usingResult.range);\r\n }\r\n offset += usingResult.linesInserted;\r\n\r\n // Step 5: Insert new test methods\r\n let testMethodInsertEnd = 0;\r\n const testMethodResult = insertTestMethods(resultLines, testMethods, baseIndent, originalLines, offset);\r\n resultLines = testMethodResult.lines;\r\n if (testMethodResult.range) {\r\n insertedRanges.push(testMethodResult.range);\r\n testMethodInsertEnd = testMethodResult.insertEnd;\r\n }\r\n offset += testMethodResult.linesInserted;\r\n\r\n // Step 6: Insert helper code right after the test methods\r\n const helperResult = insertHelperCode(\r\n resultLines, helperCode, baseIndent, originalLines, offset, testMethodInsertEnd\r\n );\r\n resultLines = helperResult.lines;\r\n if (helperResult.range) {\r\n insertedRanges.push(helperResult.range);\r\n }\r\n\r\n // Step 7: Restore the original line-ending style\r\n let testCode = resultLines.join('\\n').replace(/\\n/g, lineEnding);\r\n \r\n // Step 8: Remove trailing whitespace from each line (trim_trailing_whitespace)\r\n testCode = testCode.split(lineEnding).map(line => line.replace(/\\s+$/, '')).join(lineEnding);\r\n \r\n console.log(`Post generation (more UT) process completed, code length: ${testCode.length}`);\r\n\r\n return { testCode, insertedRanges };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Section inserters – each returns the mutated line array, the inserted range\r\n// and the number of lines added so callers can maintain an offset.\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Insert new `using` directives that don't already exist in the file.\r\n * Also injects Xap-specific usings when `isXapCode` is true.\r\n */\r\nfunction insertUsingStatements(\r\n resultLines: string[],\r\n usingStatements: string | undefined,\r\n isXapCode: boolean,\r\n testMethods: string | undefined,\r\n helperCode: string | undefined,\r\n offset: number\r\n): { lines: string[]; range: [number, number] | null; linesInserted: number } {\r\n if (!usingStatements?.trim() && !isXapCode) {\r\n return { lines: resultLines, range: null, linesInserted: 0 };\r\n }\r\n\r\n // Collect all using statements (user-provided + Xap-specific)\r\n let allUsingStatements = usingStatements ? usingStatements.replace(/\\r\\n/g, '\\n') : '';\r\n\r\n if (isXapCode) {\r\n const xapUsings = [...XAP_REQUIRED_USINGS];\r\n // Only add XapBondRelatedNamespace if generated code references XapBlob\r\n if ((testMethods && testMethods.includes('XapBlob')) || (helperCode && helperCode.includes('XapBlob'))) {\r\n xapUsings.push(XapBondRelatedNamespace);\r\n }\r\n const xapUsingsStr = xapUsings.join('\\n');\r\n allUsingStatements = allUsingStatements ? `${allUsingStatements}\\n${xapUsingsStr}` : xapUsingsStr;\r\n }\r\n\r\n // De-duplicate against the original file AND within the merged list itself\r\n const existingUsings = extractExistingUsingStatements(resultLines);\r\n const newUsingLines = allUsingStatements\r\n .split('\\n')\r\n .filter(line => line.trim() !== '')\r\n .filter(line => {\r\n const normalized = normalizeUsingStatement(line);\r\n if (!normalized || existingUsings.has(normalized)) return false;\r\n return existingUsings.add(normalized); // Set.add() returns the Set (truthy)\r\n });\r\n\r\n if (newUsingLines.length === 0) {\r\n console.log('All using statements already exist in the original file, skipping insertion.');\r\n return { lines: resultLines, range: null, linesInserted: 0 };\r\n }\r\n\r\n // Determine where and with what indentation to insert\r\n const { insertIndex: insertUsingAt, indent: usingIndent } = detectUsingInsertPosition(resultLines);\r\n const indentedUsing = applyIndentation(newUsingLines.join('\\n'), usingIndent);\r\n const usingLines = indentedUsing.split('\\n').filter(line => line.trim() !== '');\r\n\r\n const insertIndex = insertUsingAt + offset;\r\n resultLines.splice(insertIndex, 0, ...usingLines);\r\n\r\n const usingStartLine = insertIndex + 1;\r\n const usingEndLine = insertIndex + usingLines.length;\r\n console.log(`Inserted ${usingLines.length} using lines at index ${insertIndex}, range: [${usingStartLine}, ${usingEndLine}]`);\r\n\r\n return { lines: resultLines, range: [usingStartLine, usingEndLine], linesInserted: usingLines.length };\r\n}\r\n\r\n/**\r\n * Insert new test methods after the last existing test method in the file.\r\n * Falls back to inserting after the test-class opening brace when no methods exist.\r\n */\r\nfunction insertTestMethods(\r\n resultLines: string[],\r\n testMethods: string | undefined,\r\n baseIndent: string,\r\n originalLines: string[],\r\n offset: number\r\n): { lines: string[]; range: [number, number] | null; linesInserted: number; insertEnd: number } {\r\n if (!testMethods?.trim()) {\r\n return { lines: resultLines, range: null, linesInserted: 0, insertEnd: 0 };\r\n }\r\n\r\n const normalizedTestMethods = testMethods.replace(/\\r\\n/g, '\\n');\r\n const testMethodBlocks = extractTestMethodBlocks(normalizedTestMethods);\r\n const existingTestMethodNames = collectTestMethodNames(resultLines);\r\n const keptBlocks = testMethodBlocks.filter(block => {\r\n if (!block.methodName) return true;\r\n if (existingTestMethodNames.has(block.methodName)) {\r\n console.log(`Skip duplicate test method: ${block.methodName}`);\r\n return false;\r\n }\r\n existingTestMethodNames.add(block.methodName);\r\n return true;\r\n });\r\n\r\n if (keptBlocks.length === 0) {\r\n console.log('All generated test methods already exist in the original file, skipping insertion.');\r\n return { lines: resultLines, range: null, linesInserted: 0, insertEnd: 0 };\r\n }\r\n\r\n const indentedBlocks = keptBlocks.map(block => applyIndentation(block.content, baseIndent));\r\n const testMethodLines = indentedBlocks.join('\\n\\n').split('\\n');\r\n\r\n // Find the insertion point in the *original* file (before any offset)\r\n let calculatedInsertLine = findLastTestMethodEndLine(originalLines);\r\n if (calculatedInsertLine === 0) {\r\n calculatedInsertLine = findTestClassInsertPosition(originalLines);\r\n if (calculatedInsertLine === 0) {\r\n console.error('Failed to find insert position for new test methods');\r\n return { lines: resultLines, range: null, linesInserted: 0, insertEnd: 0 };\r\n }\r\n console.log('No existing test methods found, inserting after test class opening brace');\r\n }\r\n\r\n const insertMethodAt = calculatedInsertLine - 1 + offset;\r\n\r\n // Prepend an empty line for readability\r\n resultLines.splice(insertMethodAt, 0, '', ...testMethodLines);\r\n\r\n const linesInserted = testMethodLines.length + 1; // +1 for empty line\r\n const methodStartLine = insertMethodAt + 1;\r\n const methodEndLine = insertMethodAt + linesInserted;\r\n const insertEnd = insertMethodAt + linesInserted;\r\n console.log(`Inserted ${linesInserted} lines (including empty line) at index ${insertMethodAt}, range: [${methodStartLine}, ${methodEndLine}]`);\r\n\r\n return { lines: resultLines, range: [methodStartLine, methodEndLine], linesInserted, insertEnd };\r\n}\r\n\r\n/**\r\n * Insert helper / utility code immediately after the newly inserted test methods.\r\n * Falls back to appending after the last test method if no new methods were inserted.\r\n */\r\nfunction insertHelperCode(\r\n resultLines: string[],\r\n helperCode: string | undefined,\r\n baseIndent: string,\r\n originalLines: string[],\r\n offset: number,\r\n testMethodInsertEnd: number\r\n): { lines: string[]; range: [number, number] | null; linesInserted: number } {\r\n if (!helperCode?.trim()) {\r\n return { lines: resultLines, range: null, linesInserted: 0 };\r\n }\r\n\r\n const normalizedHelperCode = helperCode.replace(/\\r\\n/g, '\\n');\r\n const helperBlocks = splitTopLevelBlocks(normalizedHelperCode);\r\n const existingMethodNames = collectAllMethodNames(resultLines);\r\n const existingNormalizedContent = normalizeCodeForComparison(resultLines.join('\\n'));\r\n const seenNormalizedFragments = new Set<string>();\r\n\r\n const keptBlocks: string[] = [];\r\n for (const block of helperBlocks) {\r\n const methodName = getMethodNameFromBlock(block);\r\n if (methodName) {\r\n if (existingMethodNames.has(methodName)) {\r\n console.log(`Skip duplicate helper method: ${methodName}`);\r\n continue;\r\n }\r\n existingMethodNames.add(methodName);\r\n keptBlocks.push(block);\r\n continue;\r\n }\r\n\r\n if (containsNormalizedFragment(existingNormalizedContent, block)) {\r\n console.log('Skip duplicate helper non-method block by normalized-content check.');\r\n continue;\r\n }\r\n\r\n const normalizedBlock = normalizeCodeForComparison(block);\r\n if (seenNormalizedFragments.has(normalizedBlock)) {\r\n console.log('Skip duplicate helper non-method block within generated HELPER_CODE.');\r\n continue;\r\n }\r\n seenNormalizedFragments.add(normalizedBlock);\r\n\r\n keptBlocks.push(block);\r\n }\r\n\r\n if (keptBlocks.length === 0) {\r\n console.log('All helper code already exists in the original file, skipping insertion.');\r\n return { lines: resultLines, range: null, linesInserted: 0 };\r\n }\r\n\r\n const indentedHelperCode = keptBlocks.map(block => applyIndentation(block, baseIndent)).join('\\n\\n');\r\n const helperLines = indentedHelperCode.split('\\n');\r\n\r\n // Determine insertion point: right after test methods, or fallback\r\n let insertHelperAt: number;\r\n if (testMethodInsertEnd > 0) {\r\n insertHelperAt = testMethodInsertEnd;\r\n } else {\r\n let helperInsertLine = findLastTestMethodEndLine(originalLines);\r\n if (helperInsertLine === 0) {\r\n helperInsertLine = findTestClassInsertPosition(originalLines);\r\n }\r\n insertHelperAt = helperInsertLine - 1 + offset;\r\n }\r\n\r\n resultLines.splice(insertHelperAt, 0, ...helperLines);\r\n\r\n const helperStartLine = insertHelperAt + 1;\r\n const helperEndLine = insertHelperAt + helperLines.length;\r\n console.log(`Inserted ${helperLines.length} helper code lines at index ${insertHelperAt}, range: [${helperStartLine}, ${helperEndLine}]`);\r\n\r\n return { lines: resultLines, range: [helperStartLine, helperEndLine], linesInserted: helperLines.length };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Parsing & detection helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Parse the structured LLM response into three fenced-code sections:\r\n * `USING_STATEMENTS`, `TEST_METHODS` and `HELPER_CODE`.\r\n *\r\n * Only `TEST_METHODS` is mandatory – the others may be empty.\r\n */\r\nfunction parseGeneratedMoreUtContent(content: string): ParsedMoreUtContent | undefined {\r\n if (!content || content.trim() === '') {\r\n return undefined;\r\n }\r\n\r\n const usingMatch = content.match(/```USING_STATEMENTS\\s*([\\s\\S]*?)```/);\r\n const usingStatements = usingMatch ? usingMatch[1].trim() : '';\r\n\r\n const testMethodsMatch = content.match(/```TEST_METHODS\\s*([\\s\\S]*?)```/);\r\n const testMethods = testMethodsMatch ? testMethodsMatch[1].trim() : '';\r\n\r\n const helperCodeMatch = content.match(/```HELPER_CODE\\s*([\\s\\S]*?)```/);\r\n const helperCode = helperCodeMatch ? helperCodeMatch[1].trim() : '';\r\n\r\n if (!testMethods) {\r\n console.error('Failed to parse generated content: missing TEST_METHODS');\r\n return undefined;\r\n }\r\n\r\n return { usingStatements, testMethods, helperCode };\r\n}\r\n\r\n/**\r\n * Detect the line-ending convention used in the file.\r\n * @returns `'\\r\\n'` for Windows (CRLF) or `'\\n'` for Unix (LF).\r\n */\r\nexport function detectLineEnding(content: string): string {\r\n return content.includes('\\r\\n') ? '\\r\\n' : '\\n';\r\n}\r\n\r\n/**\r\n * Collect all `using` directives already present in the file.\r\n * @returns A `Set` of normalised using strings for O(1) de-duplication.\r\n */\r\nexport function extractExistingUsingStatements(lines: string[]): Set<string> {\r\n const existingUsings = new Set<string>();\r\n for (const line of lines) {\r\n const normalized = normalizeUsingStatement(line);\r\n if (normalized) {\r\n existingUsings.add(normalized);\r\n }\r\n }\r\n return existingUsings;\r\n}\r\n\r\n/**\r\n * Normalise a `using` directive for comparison.\r\n * Strips whitespace and trailing semicolons so that\r\n * `\" using System.Linq ; \"` and `\"using System.Linq\"` match.\r\n *\r\n * @returns `null` when the line is not a using directive.\r\n */\r\nexport function normalizeUsingStatement(line: string): string | null {\r\n const trimmed = line.trim();\r\n if (!trimmed.startsWith('using ') || trimmed.includes('(')) {\r\n return null;\r\n }\r\n return trimmed.replace(/;?\\s*$/, '').replace(/\\s+/g, ' ');\r\n}\r\n\r\n/**\r\n * Detect the indentation level of test methods in the file\r\n * by looking for `[TestMethod]`, `[Test]`, `[Fact]` or `[Theory]` attributes.\r\n *\r\n * Falls back to the first non-empty line inside a class body,\r\n * or 8 spaces if nothing useful is found.\r\n */\r\nexport function detectTestMethodIndent(lines: string[]): string {\r\n const testMethodPatterns = [\r\n /\\[TestMethod\\]/i,\r\n /\\[Test\\]/i,\r\n /\\[Fact\\]/i,\r\n /\\[Theory\\]/i\r\n ];\r\n\r\n // Try to match an existing test-method attribute\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n for (const pattern of testMethodPatterns) {\r\n if (pattern.test(line)) {\r\n const match = line.match(/^(\\s*)/);\r\n return match ? match[1] : '';\r\n }\r\n }\r\n }\r\n\r\n // Fallback: use the first non-empty line inside a class body\r\n const classPattern = /^\\s*(public\\s+)?(partial\\s+)?class\\s+/i;\r\n for (let i = 0; i < lines.length; i++) {\r\n if (classPattern.test(lines[i])) {\r\n for (let j = i; j < lines.length; j++) {\r\n if (lines[j].includes('{')) {\r\n for (let k = j + 1; k < lines.length; k++) {\r\n const nextLine = lines[k];\r\n if (nextLine.trim() !== '' && !nextLine.trim().startsWith('}')) {\r\n const match = nextLine.match(/^(\\s*)/);\r\n if (match && match[1].length > 0) {\r\n return match[1];\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n\r\n return ' '; // default: 8 spaces\r\n}\r\n\r\n/**\r\n * Re-indent a block of code so its minimum indentation matches `baseIndent`,\r\n * while preserving the *relative* indentation of nested lines.\r\n */\r\nexport function applyIndentation(code: string, baseIndent: string): string {\r\n const lines = code.split('\\n');\r\n const result: string[] = [];\r\n\r\n // Detect existing minimum indentation\r\n let minIndent = Infinity;\r\n for (const line of lines) {\r\n if (line.trim() === '') continue;\r\n const match = line.match(/^(\\s*)/);\r\n const indent = match ? match[1].length : 0;\r\n if (indent < minIndent) {\r\n minIndent = indent;\r\n }\r\n }\r\n if (minIndent === Infinity) minIndent = 0;\r\n\r\n for (const line of lines) {\r\n if (line.trim() === '') {\r\n result.push('');\r\n } else {\r\n const match = line.match(/^(\\s*)/);\r\n const currentIndent = match ? match[1].length : 0;\r\n const relativeIndent = currentIndent - minIndent;\r\n const newIndent = baseIndent + ' '.repeat(relativeIndent);\r\n result.push(newIndent + line.trim());\r\n }\r\n }\r\n\r\n return result.join('\\n');\r\n}\r\n\r\n/**\r\n * Find the 1-based line number immediately after the last test method's\r\n * closing brace. Returns 0 when no test method is found.\r\n */\r\nexport function findLastTestMethodEndLine(lines: string[]): number {\r\n const testMethodPatterns = [\r\n /\\[TestMethod\\]/i,\r\n /\\[Test\\]/i,\r\n /\\[Fact\\]/i,\r\n /\\[Theory\\]/i\r\n ];\r\n\r\n let lastTestMethodStartIndex = -1;\r\n\r\n // Scan backwards for the last test-method attribute\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n const line = lines[i].trim();\r\n for (const pattern of testMethodPatterns) {\r\n if (pattern.test(line)) {\r\n lastTestMethodStartIndex = i;\r\n break;\r\n }\r\n }\r\n if (lastTestMethodStartIndex !== -1) break;\r\n }\r\n\r\n if (lastTestMethodStartIndex === -1) {\r\n return 0;\r\n }\r\n\r\n // Walk forward tracking brace depth to locate the matching closing brace\r\n // Skips braces inside strings, verbatim strings, char literals, and comments\r\n let braceCount = 0;\r\n let foundOpeningBrace = false;\r\n let inMultiLineComment = false;\r\n\r\n for (let i = lastTestMethodStartIndex; i < lines.length; i++) {\r\n const line = lines[i];\r\n let inString = false;\r\n let inVerbatimString = false;\r\n let inCharLiteral = false;\r\n\r\n for (let j = 0; j < line.length; j++) {\r\n const ch = line[j];\r\n const next = j + 1 < line.length ? line[j + 1] : '';\r\n\r\n // Inside multi-line comment: look for */\r\n if (inMultiLineComment) {\r\n if (ch === '*' && next === '/') {\r\n inMultiLineComment = false;\r\n j++;\r\n }\r\n continue;\r\n }\r\n\r\n // Inside verbatim string: only \"\" (escaped quote) or closing \"\r\n if (inVerbatimString) {\r\n if (ch === '\"') {\r\n if (next === '\"') { j++; } // escaped quote\r\n else { inVerbatimString = false; }\r\n }\r\n continue;\r\n }\r\n\r\n // Inside regular string: handle \\\" escape\r\n if (inString) {\r\n if (ch === '\\\\') { j++; }\r\n else if (ch === '\"') { inString = false; }\r\n continue;\r\n }\r\n\r\n // Inside char literal: handle \\' escape\r\n if (inCharLiteral) {\r\n if (ch === '\\\\') { j++; }\r\n else if (ch === '\\'') { inCharLiteral = false; }\r\n continue;\r\n }\r\n\r\n // Detect start of comments, strings, char literals\r\n if (ch === '/' && next === '/') { break; } // single-line comment: skip rest of line\r\n if (ch === '/' && next === '*') { inMultiLineComment = true; j++; continue; }\r\n if (ch === '@' && next === '\"') { inVerbatimString = true; j++; continue; }\r\n if (ch === '\"') { inString = true; continue; }\r\n if (ch === '\\'') { inCharLiteral = true; continue; }\r\n\r\n // Count braces in actual code\r\n if (ch === '{') {\r\n braceCount++;\r\n foundOpeningBrace = true;\r\n } else if (ch === '}') {\r\n braceCount--;\r\n if (foundOpeningBrace && braceCount === 0) {\r\n return i + 2; // i is 0-based → +1 for 1-based, +1 for *next* line\r\n }\r\n }\r\n }\r\n }\r\n\r\n return 0;\r\n}\r\n\r\n/**\r\n * Find the 1-based line number right after the test class's opening brace.\r\n * Used as a fallback when there are no existing test methods.\r\n */\r\nexport function findTestClassInsertPosition(lines: string[]): number {\r\n const testClassPatterns = [/\\[TestClass\\]/i, /\\[TestFixture\\]/i];\r\n const classPattern = /^\\s*(public\\s+)?(partial\\s+)?class\\s+\\w*Test\\w*/i;\r\n\r\n let testClassAttributeIndex = -1;\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n for (const pattern of testClassPatterns) {\r\n if (pattern.test(line)) {\r\n testClassAttributeIndex = i;\r\n break;\r\n }\r\n }\r\n if (testClassAttributeIndex !== -1) break;\r\n }\r\n\r\n const searchStartIndex = testClassAttributeIndex !== -1 ? testClassAttributeIndex : 0;\r\n let classDeclarationIndex = -1;\r\n\r\n for (let i = searchStartIndex; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (classPattern.test(line) || (testClassAttributeIndex !== -1 && /^\\s*(public\\s+)?(partial\\s+)?class\\s+/i.test(line))) {\r\n classDeclarationIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (classDeclarationIndex === -1) {\r\n return 0;\r\n }\r\n\r\n for (let i = classDeclarationIndex; i < lines.length; i++) {\r\n if (lines[i].indexOf('{') !== -1) {\r\n return i + 2; // 0-based → +1 for 1-based, +1 for *next* line\r\n }\r\n }\r\n\r\n return 0;\r\n}\r\n\r\nfunction extractTestMethodBlocks(content: string): { methodName: string | null; content: string }[] {\r\n const lines = content.split('\\n');\r\n const testMethodPatterns = [\r\n /\\[TestMethod\\]/i,\r\n /\\[Test\\]/i,\r\n /\\[Fact\\]/i,\r\n /\\[Theory\\]/i\r\n ];\r\n\r\n const visitedStarts = new Set<number>();\r\n const blocks: { methodName: string | null; content: string }[] = [];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n const isTestAttr = testMethodPatterns.some(pattern => pattern.test(line));\r\n if (!isTestAttr) continue;\r\n\r\n const range = findTestMethodRangeByBrace(lines, i);\r\n if (!range || visitedStarts.has(range.start)) continue;\r\n visitedStarts.add(range.start);\r\n\r\n const blockLines = lines.slice(range.start, range.end + 1);\r\n let methodName: string | null = null;\r\n for (const blockLine of blockLines) {\r\n const trimmed = blockLine.trim();\r\n if (!trimmed || trimmed.startsWith('[')) continue;\r\n methodName = extractMethodName(trimmed) || null;\r\n if (methodName) break;\r\n }\r\n\r\n blocks.push({ methodName, content: blockLines.join('\\n') });\r\n }\r\n\r\n if (blocks.length > 0) {\r\n return blocks;\r\n }\r\n\r\n return [{ methodName: null, content }];\r\n}\r\n\r\nfunction collectTestMethodNames(lines: string[]): Set<string> {\r\n const names = new Set<string>();\r\n const testMethodPatterns = [\r\n /\\[TestMethod\\]/i,\r\n /\\[Test\\]/i,\r\n /\\[Fact\\]/i,\r\n /\\[Theory\\]/i\r\n ];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n const isTestAttr = testMethodPatterns.some(pattern => pattern.test(line));\r\n if (!isTestAttr) continue;\r\n\r\n const range = findTestMethodRangeByBrace(lines, i);\r\n if (!range) continue;\r\n\r\n for (let j = range.start; j <= range.end; j++) {\r\n const trimmed = lines[j].trim();\r\n if (!trimmed || trimmed.startsWith('[')) continue;\r\n const name = extractMethodName(trimmed);\r\n if (name) {\r\n names.add(name);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return names;\r\n}\r\n\r\nfunction collectAllMethodNames(lines: string[]): Set<string> {\r\n const names = new Set<string>();\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!isLikelyMethodSignature(trimmed)) continue;\r\n const name = extractMethodName(trimmed);\r\n if (name) names.add(name);\r\n }\r\n return names;\r\n}\r\n\r\nfunction splitTopLevelBlocks(content: string): string[] {\r\n const lines = content.split('\\n');\r\n const blocks: string[] = [];\r\n let current: string[] = [];\r\n let braceDepth = 0;\r\n\r\n const flushCurrent = () => {\r\n if (current.length === 0) return;\r\n const block = current.join('\\n').trim();\r\n if (block) blocks.push(block);\r\n current = [];\r\n };\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n\r\n if (trimmed === '' && current.length === 0) {\r\n continue;\r\n }\r\n\r\n current.push(line);\r\n braceDepth += countChar(line, '{');\r\n braceDepth -= countChar(line, '}');\r\n\r\n if (braceDepth <= 0 && current.length > 0) {\r\n flushCurrent();\r\n braceDepth = 0;\r\n }\r\n }\r\n\r\n flushCurrent();\r\n return blocks;\r\n}\r\n\r\nfunction getMethodNameFromBlock(block: string): string | null {\r\n const lines = block.split('\\n');\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('[')) continue;\r\n if (!isLikelyMethodSignature(trimmed)) return null;\r\n const name = extractMethodName(trimmed);\r\n return name || null;\r\n }\r\n return null;\r\n}\r\n\r\nfunction isLikelyMethodSignature(line: string): boolean {\r\n if (!/^(public|private|protected|internal)\\b/.test(line)) return false;\r\n if (/\\b(class|interface|enum|struct|record)\\b/.test(line)) return false;\r\n if (!line.includes('(') || !line.includes(')')) return false;\r\n return true;\r\n}\r\n\r\nfunction normalizeCodeForComparison(code: string): string {\r\n return code\r\n .replace(/\\r\\n/g, '\\n')\r\n .split('\\n')\r\n .map(line => line.trim())\r\n .filter(line => line !== '')\r\n .join('\\n')\r\n .replace(/\\s+/g, ' ')\r\n .trim();\r\n}\r\n\r\nfunction containsNormalizedFragment(existingNormalizedContent: string, fragment: string): boolean {\r\n const normalizedFragment = normalizeCodeForComparison(fragment);\r\n if (!normalizedFragment) {\r\n return true;\r\n }\r\n return existingNormalizedContent.includes(normalizedFragment);\r\n}\r\n\r\nfunction countChar(value: string, target: string): number {\r\n let count = 0;\r\n for (const ch of value) {\r\n if (ch === target) count++;\r\n }\r\n return count;\r\n}\r\n"]}
|
package/out/utils/spawnExec.js
CHANGED
|
@@ -48,7 +48,10 @@ function runSpawn(execCmd, args, workDir, errorHandler, closeHandler) {
|
|
|
48
48
|
cwd: workDir,
|
|
49
49
|
detached: true,
|
|
50
50
|
windowsHide: true, // Hide the console window on Windows
|
|
51
|
-
|
|
51
|
+
// stdin: 'ignore' prevents child processes (MSBuild/NuGet/vstest) from hanging
|
|
52
|
+
// when they unexpectedly try to read from stdin in non-interactive environments.
|
|
53
|
+
// These tools are designed for batch execution and don't require stdin input.
|
|
54
|
+
stdio: ['ignore', 'pipe', 'pipe'], // Pipe stdout and stderr for streaming
|
|
52
55
|
// shell: true // Required to handle quoted paths and command-line arguments
|
|
53
56
|
});
|
|
54
57
|
let stdout = '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawnExec.js","sourceRoot":"","sources":["../../src/utils/spawnExec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,
|
|
1
|
+
{"version":3,"file":"spawnExec.js","sourceRoot":"","sources":["../../src/utils/spawnExec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,4BAkDC;AAvDD,2CAA6B;AAE7B,qEAA8D;AAC9D,iDAAsC;AAEtC,SAAgB,QAAQ,CAAC,OAAe,EAAE,IAAc,EAAE,OAAe,EAAE,YAAY,EAAE,YAAY;IACjG,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAElD,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,iBAAiB,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEzG,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,wDAAwD;QACxD,+DAA+D;QAC/D,MAAM,YAAY,GAAG,IAAA,qBAAK,EAAC,iBAAiB,EAAE,IAAI,EAAE;YAChD,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI,EAAE,qCAAqC;YACxD,+EAA+E;YAC/E,iFAAiF;YACjF,8EAA8E;YAC9E,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,uCAAuC;YAC1E,4EAA4E;SAC/E,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,sBAAsB;QACtB,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACpC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,sBAAsB;QACtB,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACpC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,iFAAiF;QACjF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC;YAChF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACnC,OAAO,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,kFAAkF;QAClF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC;YACnF,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAClD,OAAO,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,qCAAe,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,+BAA+B,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import * as path from 'path';\r\n\r\nimport { childProcessSet } from '../exit/childProcessManager';\r\nimport { spawn } from 'child_process';\r\n\r\nexport function runSpawn(execCmd: string, args: string[], workDir: string, errorHandler, closeHandler): Promise<any> {\r\n return new Promise((resolve) => {\r\n const normalizedCommand = path.normalize(execCmd);\r\n\r\n console.log(`Running ${path.basename(normalizedCommand)}:\\n ${normalizedCommand} ${args.join(' ')} ...`);\r\n\r\n const startTime = Date.now();\r\n // Split command into executable and arguments for spawn\r\n // const childProcess = spawn(`\"${normalizedCommand}\"`, args, {\r\n const childProcess = spawn(normalizedCommand, args, {\r\n cwd: workDir,\r\n detached: true,\r\n windowsHide: true, // Hide the console window on Windows\r\n // stdin: 'ignore' prevents child processes (MSBuild/NuGet/vstest) from hanging\r\n // when they unexpectedly try to read from stdin in non-interactive environments.\r\n // These tools are designed for batch execution and don't require stdin input.\r\n stdio: ['ignore', 'pipe', 'pipe'], // Pipe stdout and stderr for streaming\r\n // shell: true // Required to handle quoted paths and command-line arguments\r\n });\r\n\r\n let stdout = '';\r\n let stderr = '';\r\n\r\n // Collect stdout data\r\n childProcess.stdout.on('data', (data) => {\r\n stdout += data.toString();\r\n });\r\n\r\n // Collect stderr data\r\n childProcess.stderr.on('data', (data) => {\r\n stderr += data.toString();\r\n });\r\n\r\n // Handle process errors, case: the cmd can't be executed, like path not found...\r\n childProcess.on('error', (error) => {\r\n console.log(`exec error cost time: ${(Date.now() - startTime) / 1000} seconds`);\r\n const result = errorHandler(error);\r\n resolve(result);\r\n });\r\n\r\n // Handle process exit, case: the cmd executed but failed with error, or succeeded\r\n childProcess.on('close', (code) => {\r\n console.log(`exec complete cost time: ${(Date.now() - startTime) / 1000} seconds`);\r\n const result = closeHandler(code, stdout, stderr);\r\n resolve(result);\r\n });\r\n\r\n childProcessSet.add(childProcess.pid);\r\n console.log(`Running spawnExec with PID: ${childProcess.pid}`);\r\n });\r\n}"]}
|