@ai-dev-tools/csharp-copilot-core 0.0.36 → 0.0.38
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/autoFix.d.ts +1 -1
- package/out/gen/autoFix.js +10 -5
- package/out/gen/autoFix.js.map +1 -1
- package/out/gen/ensureValidLLMResponse.d.ts +1 -1
- package/out/gen/ensureValidLLMResponse.js +6 -2
- package/out/gen/ensureValidLLMResponse.js.map +1 -1
- package/out/gen/postGen/postGenMoreUTAutofixProcess.d.ts +17 -0
- package/out/gen/postGen/postGenMoreUTAutofixProcess.js +475 -0
- package/out/gen/postGen/postGenMoreUTAutofixProcess.js.map +1 -0
- package/out/gen/postGen/postGenMoreUTProcess.d.ts +41 -0
- package/out/gen/postGen/postGenMoreUTProcess.js +14 -2
- package/out/gen/postGen/postGenMoreUTProcess.js.map +1 -1
- package/out/llm/prompt/moreUT/generateMoreUtAutoFix.liquid +1 -0
- package/out/utils/getTestFile.js +1 -1
- package/out/utils/getTestFile.js.map +1 -1
- package/out/utils/moreUTAutoFixUtil.d.ts +7 -0
- package/out/utils/moreUTAutoFixUtil.js +51 -0
- package/out/utils/moreUTAutoFixUtil.js.map +1 -0
- package/out/utils/removeFailedTestMethods.d.ts +12 -0
- package/out/utils/removeFailedTestMethods.js +18 -16
- package/out/utils/removeFailedTestMethods.js.map +1 -1
- package/out/utils/writeGenCode.d.ts +5 -0
- package/out/utils/writeGenCode.js +15 -0
- package/out/utils/writeGenCode.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract test method names that contain errors from build or test results.
|
|
3
|
+
*
|
|
4
|
+
* - Build failure: uses error line numbers to find the enclosing test method in the code.
|
|
5
|
+
* - Test failure: directly reads failed test names from the test result.
|
|
6
|
+
*/
|
|
7
|
+
export declare function extractErrorTestMethodNames(testCode: string, isBuildFailure: boolean, buildResult?: any, testResult?: any): string[];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractErrorTestMethodNames = extractErrorTestMethodNames;
|
|
4
|
+
const removeFailedTestMethods_1 = require("./removeFailedTestMethods");
|
|
5
|
+
/**
|
|
6
|
+
* Extract test method names that contain errors from build or test results.
|
|
7
|
+
*
|
|
8
|
+
* - Build failure: uses error line numbers to find the enclosing test method in the code.
|
|
9
|
+
* - Test failure: directly reads failed test names from the test result.
|
|
10
|
+
*/
|
|
11
|
+
function extractErrorTestMethodNames(testCode, isBuildFailure, buildResult, testResult) {
|
|
12
|
+
const methodNames = new Set();
|
|
13
|
+
if (isBuildFailure && buildResult) {
|
|
14
|
+
// Build errors: find test method by error line number
|
|
15
|
+
const errors = Array.isArray(buildResult) ? buildResult : (buildResult.errors || []);
|
|
16
|
+
const lines = testCode?.split('\n') || [];
|
|
17
|
+
for (const err of errors) {
|
|
18
|
+
const errorLine = err.line;
|
|
19
|
+
if (!errorLine)
|
|
20
|
+
continue;
|
|
21
|
+
const range = (0, removeFailedTestMethods_1.findTestMethodRangeByBrace)(lines, errorLine - 1); // 0-based
|
|
22
|
+
if (range) {
|
|
23
|
+
// Find method name within the range
|
|
24
|
+
for (let i = range.start; i <= range.end; i++) {
|
|
25
|
+
const trimmed = lines[i].trim();
|
|
26
|
+
if (!trimmed.startsWith('[') && trimmed !== '' && /\b\w+\s*\(/.test(trimmed)) {
|
|
27
|
+
const name = (0, removeFailedTestMethods_1.extractMethodName)(trimmed);
|
|
28
|
+
if (name) {
|
|
29
|
+
methodNames.add(name);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (!isBuildFailure && testResult?.failedTests) {
|
|
38
|
+
// Test errors: directly use failed test names
|
|
39
|
+
for (const failed of testResult.failedTests) {
|
|
40
|
+
if (failed.name) {
|
|
41
|
+
methodNames.add(failed.name);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const result = Array.from(methodNames);
|
|
46
|
+
if (result.length > 0) {
|
|
47
|
+
console.log(`Extracted error test method names: ${result.join(', ')}`);
|
|
48
|
+
}
|
|
49
|
+
return result.length > 0 ? result : undefined;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=moreUTAutoFixUtil.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moreUTAutoFixUtil.js","sourceRoot":"","sources":["../../src/utils/moreUTAutoFixUtil.ts"],"names":[],"mappings":";;AAQA,kEA4CC;AApDD,uEAA0F;AAE1F;;;;;GAKG;AACH,SAAgB,2BAA2B,CACvC,QAAgB,EAChB,cAAuB,EACvB,WAAiB,EACjB,UAAgB;IAEhB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAEtC,IAAI,cAAc,IAAI,WAAW,EAAE,CAAC;QAChC,sDAAsD;QACtD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QACrF,MAAM,KAAK,GAAG,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC;YAC3B,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,MAAM,KAAK,GAAG,IAAA,oDAA0B,EAAC,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU;YAC1E,IAAI,KAAK,EAAE,CAAC;gBACR,oCAAoC;gBACpC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBAChC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC3E,MAAM,IAAI,GAAG,IAAA,2CAAiB,EAAC,OAAO,CAAC,CAAC;wBACxC,IAAI,IAAI,EAAE,CAAC;4BACP,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;4BACtB,MAAM;wBACV,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;SAAM,IAAI,CAAC,cAAc,IAAI,UAAU,EAAE,WAAW,EAAE,CAAC;QACpD,8CAA8C;QAC9C,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YAC1C,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBACd,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;QACL,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,sCAAsC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC","sourcesContent":["import { findTestMethodRangeByBrace, extractMethodName } from './removeFailedTestMethods';\r\n\r\n/**\r\n * Extract test method names that contain errors from build or test results.\r\n *\r\n * - Build failure: uses error line numbers to find the enclosing test method in the code.\r\n * - Test failure: directly reads failed test names from the test result.\r\n */\r\nexport function extractErrorTestMethodNames(\r\n testCode: string,\r\n isBuildFailure: boolean,\r\n buildResult?: any,\r\n testResult?: any\r\n): string[] {\r\n const methodNames = new Set<string>();\r\n\r\n if (isBuildFailure && buildResult) {\r\n // Build errors: find test method by error line number\r\n const errors = Array.isArray(buildResult) ? buildResult : (buildResult.errors || []);\r\n const lines = testCode?.split('\\n') || [];\r\n for (const err of errors) {\r\n const errorLine = err.line;\r\n if (!errorLine) continue;\r\n const range = findTestMethodRangeByBrace(lines, errorLine - 1); // 0-based\r\n if (range) {\r\n // Find method name within the range\r\n for (let i = range.start; i <= range.end; i++) {\r\n const trimmed = lines[i].trim();\r\n if (!trimmed.startsWith('[') && trimmed !== '' && /\\b\\w+\\s*\\(/.test(trimmed)) {\r\n const name = extractMethodName(trimmed);\r\n if (name) {\r\n methodNames.add(name);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n } else if (!isBuildFailure && testResult?.failedTests) {\r\n // Test errors: directly use failed test names\r\n for (const failed of testResult.failedTests) {\r\n if (failed.name) {\r\n methodNames.add(failed.name);\r\n }\r\n }\r\n }\r\n\r\n const result = Array.from(methodNames);\r\n if (result.length > 0) {\r\n console.log(`Extracted error test method names: ${result.join(', ')}`);\r\n }\r\n return result.length > 0 ? result : undefined;\r\n}\r\n"]}
|
|
@@ -2,6 +2,10 @@ import { GenResult } from '../types/genResult';
|
|
|
2
2
|
import { BuildResult } from '../types/buildResult';
|
|
3
3
|
import { TestResult } from '../types/testResult';
|
|
4
4
|
export declare function removeFailedTests(filePath: string, failedTestNames: string[]): string;
|
|
5
|
+
/**
|
|
6
|
+
* extract method name from a method definition line
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractMethodName(line: string): string;
|
|
5
9
|
export declare function removeFailedTestCasesInTestFile(vsTestRes: TestResult, testFilePath: string): void;
|
|
6
10
|
/**
|
|
7
11
|
* Try to remove failed test methods and verify if the remaining code is valid.
|
|
@@ -9,3 +13,11 @@ export declare function removeFailedTestCasesInTestFile(vsTestRes: TestResult, t
|
|
|
9
13
|
* If buildResult has errors, remove the test methods containing build errors and verify.
|
|
10
14
|
*/
|
|
11
15
|
export declare function removeFailedTestMethods(testCode: string, testFilePath: string, testProjectPath: string, sourceCodePath: string, buildResult: BuildResult[] | null, testResult: TestResult | null, isVsPlugin: boolean, originalTestLength?: number): Promise<GenResult | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Find the start and end line indices of the test method containing the given line.
|
|
18
|
+
* Includes all attributes above the test method attribute (e.g., [DataRow], [Category], etc.)
|
|
19
|
+
*/
|
|
20
|
+
export declare function findTestMethodRangeByBrace(lines: string[], targetLineIndex: number): {
|
|
21
|
+
start: number;
|
|
22
|
+
end: number;
|
|
23
|
+
} | null;
|
|
@@ -34,13 +34,29 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.removeFailedTests = removeFailedTests;
|
|
37
|
+
exports.extractMethodName = extractMethodName;
|
|
37
38
|
exports.removeFailedTestCasesInTestFile = removeFailedTestCasesInTestFile;
|
|
38
39
|
exports.removeFailedTestMethods = removeFailedTestMethods;
|
|
40
|
+
exports.findTestMethodRangeByBrace = findTestMethodRangeByBrace;
|
|
39
41
|
const fs = __importStar(require("fs"));
|
|
40
42
|
const constants_1 = require("../types/constants");
|
|
41
43
|
const checkCodeSyntax_1 = require("../analyze/checkCodeSyntax");
|
|
42
44
|
const verifyGeneratedCode_1 = require("./verifyGeneratedCode");
|
|
43
45
|
const fileUtils_1 = require("./fileUtils");
|
|
46
|
+
/**
|
|
47
|
+
* Remove lines at the given 0-based indices from `code`, then collapse
|
|
48
|
+
* consecutive blank / whitespace-only lines down to a single blank line.
|
|
49
|
+
*/
|
|
50
|
+
function removeLinesAndCleanup(code, linesToRemove) {
|
|
51
|
+
if (linesToRemove.size === 0)
|
|
52
|
+
return code;
|
|
53
|
+
const lines = code.split('\n');
|
|
54
|
+
const sorted = Array.from(linesToRemove).sort((a, b) => b - a);
|
|
55
|
+
for (const idx of sorted) {
|
|
56
|
+
lines.splice(idx, 1);
|
|
57
|
+
}
|
|
58
|
+
return lines.join('\n').replace(/(\n\s*){3,}/g, '\n\n');
|
|
59
|
+
}
|
|
44
60
|
function removeFailedTests(filePath, failedTestNames) {
|
|
45
61
|
try {
|
|
46
62
|
if (!fs.existsSync(filePath)) {
|
|
@@ -351,14 +367,7 @@ function removeFailedAssertionsOrMethods(code, errorLines) {
|
|
|
351
367
|
if (linesToRemove.size === 0) {
|
|
352
368
|
return code;
|
|
353
369
|
}
|
|
354
|
-
|
|
355
|
-
const sortedLinesToRemove = Array.from(linesToRemove).sort((a, b) => b - a);
|
|
356
|
-
for (const lineIndex of sortedLinesToRemove) {
|
|
357
|
-
lines.splice(lineIndex, 1);
|
|
358
|
-
}
|
|
359
|
-
// Clean up consecutive empty lines (replace multiple empty lines with single empty line)
|
|
360
|
-
const result = lines.join('\n').replace(/\n{3,}/g, '\n\n');
|
|
361
|
-
return result;
|
|
370
|
+
return removeLinesAndCleanup(code, linesToRemove);
|
|
362
371
|
}
|
|
363
372
|
/**
|
|
364
373
|
* Find all assert statement lines within the given line range.
|
|
@@ -487,14 +496,7 @@ function removeTestMethodsByLines(code, errorLines) {
|
|
|
487
496
|
if (linesToRemove.size === 0) {
|
|
488
497
|
return code;
|
|
489
498
|
}
|
|
490
|
-
|
|
491
|
-
const sortedLinesToRemove = Array.from(linesToRemove).sort((a, b) => b - a);
|
|
492
|
-
for (const lineIndex of sortedLinesToRemove) {
|
|
493
|
-
lines.splice(lineIndex, 1);
|
|
494
|
-
}
|
|
495
|
-
// Clean up consecutive empty lines (replace multiple empty lines with single empty line)
|
|
496
|
-
const result = lines.join('\n').replace(/\n{3,}/g, '\n\n');
|
|
497
|
-
return result;
|
|
499
|
+
return removeLinesAndCleanup(code, linesToRemove);
|
|
498
500
|
}
|
|
499
501
|
/**
|
|
500
502
|
* Find the start and end line indices of the test method containing the given line.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeFailedTestMethods.js","sourceRoot":"","sources":["../../src/utils/removeFailedTestMethods.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\r\n\r\nimport { GenResult } from '../types/genResult';\r\nimport { BuildResult } from '../types/buildResult';\r\nimport { TestResult } from '../types/testResult';\r\nimport { LINESEPARATOR } from '../types/constants';\r\nimport { checkCodeSyntax } from '../analyze/checkCodeSyntax';\r\nimport { verifyGeneratedCode } from './verifyGeneratedCode';\r\nimport { writeTestCode } from './fileUtils';\r\n\r\ninterface TestMethodInfo {\r\n startLine: number;\r\n endLine: number;\r\n methodName: string;\r\n}\r\n\r\nexport function removeFailedTests(filePath: string, failedTestNames: string[]) {\r\n try {\r\n if (!fs.existsSync(filePath)) {\r\n throw new Error(`File not exist ${filePath}`);\r\n }\r\n\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const lines = content.split(LINESEPARATOR);\r\n\r\n // get all test methods in the file\r\n const testMethods = findTestMethods(lines);\r\n\r\n // filter out methods that match the failed test names\r\n const methodsToRemove = testMethods.filter(method =>\r\n failedTestNames.includes(method.methodName)\r\n );\r\n\r\n if (methodsToRemove.length === 0) {\r\n console.log('Can not find any failed test methods to remove.');\r\n return;\r\n }\r\n\r\n // sort methods by start line in descending order\r\n // to avoid index issues when removing lines\r\n methodsToRemove.sort((a, b) => b.startLine - a.startLine);\r\n\r\n // delete the test methods from the lines\r\n let modifiedLines = [...lines];\r\n for (const method of methodsToRemove) {\r\n modifiedLines = removeTestMethod(modifiedLines, method);\r\n }\r\n\r\n // cleanup empty lines\r\n modifiedLines = cleanupEmptyLines(modifiedLines);\r\n\r\n\r\n const modifiedContent = modifiedLines.join('\\n');\r\n return modifiedContent;\r\n\r\n } catch (error) {\r\n console.error('Error removing failed tests:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * find all test methods in the file\r\n */\r\nfunction findTestMethods(lines: string[]): TestMethodInfo[] {\r\n const testMethods: TestMethodInfo[] = [];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n\r\n // find [TestMethod] attribute\r\n if (line === '[TestMethod]' || line.startsWith('[TestMethod(')) {\r\n // find the method definition starting from this line\r\n const methodInfo = findMethodDefinition(lines, i);\r\n if (methodInfo) {\r\n testMethods.push(methodInfo);\r\n }\r\n }\r\n }\r\n\r\n return testMethods;\r\n}\r\n\r\n/**\r\n * find the method definition based on the line number of [TestMethod]\r\n */\r\nfunction findMethodDefinition(lines: string[], testMethodLine: number): TestMethodInfo | null {\r\n let methodStartLine = testMethodLine;\r\n let methodName = '';\r\n let braceCount = 0;\r\n let methodFound = false;\r\n let methodEndLine = -1;\r\n\r\n // find the start of the method definition\r\n while (methodStartLine > 0 &&\r\n (lines[methodStartLine - 1].trim() === '' ||\r\n lines[methodStartLine - 1].trim().startsWith('['))) {\r\n methodStartLine--;\r\n }\r\n\r\n // find the method definition starting from the line after [TestMethod]\r\n for (let i = testMethodLine; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n\r\n // skip empty lines and section headers\r\n if (line === '' || line.startsWith('[')) {\r\n continue;\r\n }\r\n\r\n // find the method definition\r\n if (!methodFound && isMethodDefinition(line)) {\r\n methodName = extractMethodName(line);\r\n methodFound = true;\r\n\r\n // if the method is defined in a single line, we can directly set the end line\r\n const openBraces = (line.match(/{/g) || []).length;\r\n const closeBraces = (line.match(/}/g) || []).length;\r\n braceCount += openBraces - closeBraces;\r\n\r\n if (braceCount === 0 && openBraces > 0) {\r\n // single line method definition\r\n methodEndLine = i;\r\n break;\r\n }\r\n continue;\r\n }\r\n\r\n // if we have found the method definition, count braces\r\n if (methodFound) {\r\n const openBraces = (line.match(/{/g) || []).length;\r\n const closeBraces = (line.match(/}/g) || []).length;\r\n braceCount += openBraces - closeBraces;\r\n\r\n if (braceCount === 0) {\r\n methodEndLine = i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (methodFound && methodEndLine !== -1) {\r\n return {\r\n startLine: methodStartLine,\r\n endLine: methodEndLine,\r\n methodName: methodName\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * check if a line is a method definition\r\n */\r\nfunction isMethodDefinition(line: string): boolean {\r\n // simple regex to match method definitions\r\n // supports public, protected, internal, static, async, and method name with parameters\r\n const methodPattern = /^\\s*(public|function|protected|internal)?\\s*(static\\s+)?(async\\s+)?\\w+\\s+\\w+\\s*\\(/;\r\n return methodPattern.test(line);\r\n}\r\n\r\n/**\r\n * extract method name from a method definition line\r\n */\r\nfunction extractMethodName(line: string): string {\r\n const match = line.match(/\\b(\\w+)\\s*\\(/);\r\n return match ? match[1] : '';\r\n}\r\n\r\n/**\r\n * delete specific testt method block from lines\r\n */\r\nfunction removeTestMethod(lines: string[], method: TestMethodInfo): string[] {\r\n const newLines = [...lines];\r\n\r\n // delete methodn block(include [TestMethod] tag)\r\n newLines.splice(method.startLine, method.endLine - method.startLine + 1);\r\n\r\n return newLines;\r\n}\r\n\r\n/**\r\n * clean extra empty line, ensure only one empty line between methods\r\n */\r\nfunction cleanupEmptyLines(lines: string[]): string[] {\r\n const result: string[] = [];\r\n let emptyLineCount = 0;\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const isEmptyLine = line.trim() === '';\r\n\r\n if (isEmptyLine) {\r\n emptyLineCount++;\r\n // keep one empty line between methods\r\n if (emptyLineCount === 1) {\r\n result.push(line);\r\n }\r\n } else {\r\n emptyLineCount = 0;\r\n result.push(line);\r\n }\r\n }\r\n\r\n // remove trailing empty lines\r\n while (result.length > 0 && result[result.length - 1].trim() === '') {\r\n result.pop();\r\n }\r\n\r\n return result;\r\n}\r\n\r\n\r\nexport function removeFailedTestCasesInTestFile(vsTestRes: TestResult, testFilePath: string): void {\r\n const failedTestMethods = vsTestRes?.failedTests?.map(test => test.name) || [];\r\n const succeedTestCode = removeFailedTests(testFilePath, failedTestMethods);\r\n fs.writeFileSync(testFilePath, succeedTestCode, 'utf-8');\r\n console.log(`Removed failed test cases from file: ${testFilePath}`);\r\n}\r\n\r\n// const testCode = removeFailedTests(\"D:\\\\code\\\\CS.Service.Fundamental\\\\SharedSegments\\\\SharedSegments\\\\SharedSegments.Tests\\\\Workflows\\\\Overview\\\\HttpRequestParser\\\\Utils\\\\SqmidHelperTests.cs\", [\"GetSqmidFromCookie_InvalidBlisIdFormat_ReturnsEmptyString\", \"GetSqmidFromCookie_MissingUsrLocCookie_ReturnsEmptyString\"]);\r\n// console.log(testCode);\r\n\r\n/**\r\n * Try to remove failed test methods and verify if the remaining code is valid.\r\n * If testResult has errors, remove the failed test methods and check syntax.\r\n * If buildResult has errors, remove the test methods containing build errors and verify.\r\n */\r\nexport async function removeFailedTestMethods(\r\n testCode: string,\r\n testFilePath: string,\r\n testProjectPath: string,\r\n sourceCodePath: string,\r\n buildResult: BuildResult[] | null,\r\n testResult: TestResult | null,\r\n isVsPlugin: boolean,\r\n originalTestLength: number = 0\r\n): Promise<GenResult | null> {\r\n if (!testCode) {\r\n return null;\r\n }\r\n\r\n let updatedCode = testCode;\r\n\r\n // Case 1: Test errors - intelligently remove failed assertions or test methods\r\n if (testResult && testResult.failedTests && testResult.failedTests.length > 0) {\r\n console.log(\"Attempting to remove failed test methods or assertions...\");\r\n \r\n // Extract line numbers from failed test stack traces\r\n const errorLines: number[] = [];\r\n for (const failedTest of testResult.failedTests) {\r\n const lineMatches = failedTest.stackTrace.matchAll(/:line (\\d+)/g);\r\n for (const match of lineMatches) {\r\n errorLines.push(parseInt(match[1], 10));\r\n }\r\n }\r\n\r\n if (errorLines.length > 0) {\r\n updatedCode = removeFailedAssertionsOrMethods(updatedCode, errorLines);\r\n if (updatedCode !== testCode) {\r\n writeTestCode(updatedCode, testFilePath);\r\n \r\n const syntaxResult = await checkCodeSyntax(testFilePath);\r\n if (syntaxResult.success) {\r\n // Check if code length is greater than original\r\n if (originalTestLength > 0 && updatedCode.length <= originalTestLength) {\r\n console.error(\"Remaining code length is not greater than original test code length after removing failed tests.\");\r\n return null;\r\n }\r\n console.log(\"Successfully removed failed test assertions/methods, syntax check passed.\");\r\n return { success: true, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: null, testResult: null };\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Case 2: Build errors - remove test methods containing build errors\r\n if (buildResult && buildResult.length > 0) {\r\n console.log(\"Attempting to remove test methods with build errors...\");\r\n \r\n const errorLines = buildResult.map(err => err.line);\r\n updatedCode = removeTestMethodsByLines(updatedCode, errorLines);\r\n \r\n if (updatedCode !== testCode) {\r\n writeTestCode(updatedCode, testFilePath);\r\n \r\n const verifyResult = await verifyGeneratedCode(updatedCode, testProjectPath, testFilePath, isVsPlugin);\r\n \r\n if (verifyResult.success) {\r\n // Check if code length is greater than original\r\n if (originalTestLength > 0 && updatedCode.length <= originalTestLength) {\r\n console.error(\"Remaining code length is not greater than original test code length after removing build errors.\");\r\n return null;\r\n }\r\n console.log(\"Successfully removed test methods with build errors, verification passed.\");\r\n return { success: true, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: null, testResult: verifyResult.testResult };\r\n }\r\n \r\n // If still has build errors, return failure\r\n if (verifyResult.buildErrors && verifyResult.buildErrors.length > 0) {\r\n console.error(\"Still has build errors after removing test methods.\");\r\n return { success: false, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: verifyResult.buildErrors, testResult: null };\r\n }\r\n \r\n // If has test errors, try to remove failed test methods\r\n if (verifyResult.testResult && verifyResult.testResult.failedTests && verifyResult.testResult.failedTests.length > 0) {\r\n console.log(\"Build passed but has test errors, attempting to remove failed test methods...\");\r\n \r\n const testErrorLines: number[] = [];\r\n for (const failedTest of verifyResult.testResult.failedTests) {\r\n const lineMatches = failedTest.stackTrace.matchAll(/:line (\\d+)/g);\r\n for (const match of lineMatches) {\r\n testErrorLines.push(parseInt(match[1], 10));\r\n }\r\n }\r\n \r\n if (testErrorLines.length > 0) {\r\n const finalCode = removeFailedAssertionsOrMethods(updatedCode, testErrorLines);\r\n if (finalCode !== updatedCode) {\r\n writeTestCode(finalCode, testFilePath);\r\n \r\n const syntaxResult = await checkCodeSyntax(testFilePath);\r\n if (syntaxResult.success) {\r\n // Check if code length is greater than original\r\n if (originalTestLength > 0 && finalCode.length <= originalTestLength) {\r\n console.error(\"Remaining code length is not greater than original test code length after removing failed tests.\");\r\n return null;\r\n }\r\n console.log(\"Successfully removed failed test methods after build fix, syntax check passed.\");\r\n return { success: true, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: null, testResult: null };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Remove failed assertions or entire test methods based on the error lines.\r\n * Strategy:\r\n * - If only one assert in the method, remove the entire method\r\n * - If multiple asserts and the failed assert has no other asserts above it, remove the entire method\r\n * - If multiple asserts and there are asserts above the failed one, only remove from failed assert to method end\r\n */\r\nfunction removeFailedAssertionsOrMethods(code: string, errorLines: number[]): string {\r\n const lines = code.split('\\n');\r\n const linesToRemove = new Set<number>();\r\n \r\n // Process each error line\r\n for (const errorLine of errorLines) {\r\n const targetLineIndex = errorLine - 1; // Convert to 0-based index\r\n \r\n // Find the test method that contains this error line\r\n const methodRange = findTestMethodRangeByBrace(lines, targetLineIndex);\r\n if (!methodRange) {\r\n continue;\r\n }\r\n \r\n // Find all assert lines in this method\r\n const assertLines = findAssertLinesInRange(lines, methodRange.start, methodRange.end);\r\n \r\n if (assertLines.length <= 1) {\r\n // Only one assert (or none), remove the entire method\r\n for (let i = methodRange.start; i <= methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n } else {\r\n // Multiple asserts - check if there are asserts above the failed line\r\n const assertsAbove = assertLines.filter(line => line < targetLineIndex);\r\n \r\n if (assertsAbove.length === 0) {\r\n // No asserts above the failed line, remove the entire method\r\n for (let i = methodRange.start; i <= methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n } else {\r\n // There are asserts above, only remove from the failed assert line to method end\r\n // Find the start of the failed assert statement (it might span multiple lines)\r\n let assertStartLine = findAssertStatementStart(lines, targetLineIndex);\r\n \r\n // Also include comments and empty lines above the assert\r\n assertStartLine = findCodeBlockStart(lines, assertStartLine, methodRange.start);\r\n \r\n // Remove from assert start to method end (but keep the closing brace on a new line)\r\n for (let i = assertStartLine; i < methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n }\r\n }\r\n }\r\n \r\n if (linesToRemove.size === 0) {\r\n return code;\r\n }\r\n \r\n // Remove the lines (in reverse order to maintain indices)\r\n const sortedLinesToRemove = Array.from(linesToRemove).sort((a, b) => b - a);\r\n for (const lineIndex of sortedLinesToRemove) {\r\n lines.splice(lineIndex, 1);\r\n }\r\n \r\n // Clean up consecutive empty lines (replace multiple empty lines with single empty line)\r\n const result = lines.join('\\n').replace(/\\n{3,}/g, '\\n\\n');\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Find all assert statement lines within the given line range.\r\n * Supports different test frameworks: MSTest, NUnit, xUnit\r\n */\r\nfunction findAssertLinesInRange(lines: string[], startLine: number, endLine: number): number[] {\r\n const assertLines: number[] = [];\r\n \r\n // Patterns for different test frameworks\r\n // MSTest: Assert.AreEqual, Assert.IsTrue, Assert.IsFalse, Assert.IsNull, Assert.IsNotNull, Assert.ThrowsException, etc.\r\n // NUnit: Assert.AreEqual, Assert.That, Assert.IsTrue, Assert.Throws, etc.\r\n // xUnit: Assert.Equal, Assert.True, Assert.False, Assert.Null, Assert.NotNull, Assert.Throws, etc.\r\n // Also support FluentAssertions: .Should()\r\n const assertPatterns = [\r\n /\\bAssert\\s*\\./i, // Assert.xxx (MSTest, NUnit, xUnit)\r\n /\\bStringAssert\\s*\\./i, // StringAssert.xxx (MSTest)\r\n /\\bCollectionAssert\\s*\\./i, // CollectionAssert.xxx (MSTest)\r\n /\\.Should\\s*\\(/i, // FluentAssertions: xxx.Should()\r\n /\\.ShouldBe\\s*\\(/i, // Shouldly: xxx.ShouldBe()\r\n /\\.ShouldEqual\\s*\\(/i, // Shouldly variants\r\n /\\bExpect\\s*\\(/i, // NUnit Expect\r\n ];\r\n \r\n for (let i = startLine; i <= endLine; i++) {\r\n const line = lines[i];\r\n for (const pattern of assertPatterns) {\r\n if (pattern.test(line)) {\r\n assertLines.push(i);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n return assertLines;\r\n}\r\n\r\n/**\r\n * Find the start line of an assert statement (it may span multiple lines).\r\n * Searches backwards to find the actual start of the statement.\r\n */\r\nfunction findAssertStatementStart(lines: string[], assertLine: number): number {\r\n const assertPatterns = [\r\n /\\bAssert\\s*\\./i,\r\n /\\bStringAssert\\s*\\./i,\r\n /\\bCollectionAssert\\s*\\./i,\r\n /\\.Should\\s*\\(/i,\r\n /\\.ShouldBe\\s*\\(/i,\r\n /\\.ShouldEqual\\s*\\(/i,\r\n /\\bExpect\\s*\\(/i,\r\n ];\r\n \r\n // Check if current line contains an assert pattern\r\n const currentLine = lines[assertLine];\r\n for (const pattern of assertPatterns) {\r\n if (pattern.test(currentLine)) {\r\n return assertLine; // Assert starts on this line\r\n }\r\n }\r\n \r\n // If not found on current line, search backwards for the statement start\r\n // This handles cases where the assert call spans multiple lines\r\n for (let i = assertLine - 1; i >= 0; i--) {\r\n const line = lines[i];\r\n for (const pattern of assertPatterns) {\r\n if (pattern.test(line)) {\r\n return i;\r\n }\r\n }\r\n // If we hit an empty line or a line ending with semicolon or opening brace, stop\r\n const trimmedLine = line.trim();\r\n if (trimmedLine === '' || trimmedLine.endsWith(';') || trimmedLine.endsWith('{')) {\r\n break;\r\n }\r\n }\r\n \r\n return assertLine; // Fallback to the original line\r\n}\r\n\r\n/**\r\n * Find the start of a code block including comments and empty lines above it.\r\n * Searches backwards from the given line to include preceding comments and empty lines.\r\n */\r\nfunction findCodeBlockStart(lines: string[], startLine: number, minLine: number): number {\r\n let result = startLine;\r\n \r\n // Comment patterns\r\n const singleLineCommentPattern = /^\\s*\\/\\//;\r\n const blockCommentEndPattern = /\\*\\/\\s*$/;\r\n const blockCommentStartPattern = /^\\s*\\/\\*/;\r\n \r\n for (let i = startLine - 1; i >= minLine; i--) {\r\n const line = lines[i];\r\n const trimmedLine = line.trim();\r\n \r\n if (trimmedLine === '') {\r\n // Empty line, include it\r\n result = i;\r\n } else if (singleLineCommentPattern.test(line)) {\r\n // Single line comment (// comment), include it\r\n result = i;\r\n } else if (blockCommentEndPattern.test(trimmedLine)) {\r\n // End of block comment, search backwards for the start\r\n result = i;\r\n for (let j = i; j >= minLine; j--) {\r\n result = j;\r\n if (blockCommentStartPattern.test(lines[j])) {\r\n break;\r\n }\r\n }\r\n i = result; // Continue from the block comment start\r\n } else {\r\n // Hit actual code, stop\r\n break;\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Remove test methods that contain the specified line numbers.\r\n * Finds the test method boundaries and removes the entire method.\r\n */\r\nfunction removeTestMethodsByLines(code: string, errorLines: number[]): string {\r\n const lines = code.split('\\n');\r\n const linesToRemove = new Set<number>();\r\n \r\n for (const errorLine of errorLines) {\r\n // Find the test method that contains this error line\r\n const methodRange = findTestMethodRangeByBrace(lines, errorLine - 1); // Convert to 0-based index\r\n if (methodRange) {\r\n for (let i = methodRange.start; i <= methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n }\r\n }\r\n \r\n if (linesToRemove.size === 0) {\r\n return code;\r\n }\r\n \r\n // Remove the lines (in reverse order to maintain indices)\r\n const sortedLinesToRemove = Array.from(linesToRemove).sort((a, b) => b - a);\r\n for (const lineIndex of sortedLinesToRemove) {\r\n lines.splice(lineIndex, 1);\r\n }\r\n \r\n // Clean up consecutive empty lines (replace multiple empty lines with single empty line)\r\n const result = lines.join('\\n').replace(/\\n{3,}/g, '\\n\\n');\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Find the start and end line indices of the test method containing the given line.\r\n * Includes all attributes above the test method attribute (e.g., [DataRow], [Category], etc.)\r\n */\r\nfunction findTestMethodRangeByBrace(lines: string[], targetLineIndex: number): { start: number, end: number } | null {\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 // Pattern to match any C# attribute\r\n const attributePattern = /^\\s*\\[.+\\]\\s*$/;\r\n \r\n // Search backwards to find the test method attribute\r\n let testAttributeLine = -1;\r\n for (let i = targetLineIndex; 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 testAttributeLine = i;\r\n break;\r\n }\r\n }\r\n if (testAttributeLine !== -1) break;\r\n }\r\n \r\n if (testAttributeLine === -1) {\r\n return null; // Not inside a test method\r\n }\r\n \r\n // Search upward from test attribute to include all consecutive attributes above it\r\n // (e.g., [DataRow], [Category], [Description], etc.)\r\n let methodStart = testAttributeLine;\r\n for (let i = testAttributeLine - 1; i >= 0; i--) {\r\n const line = lines[i].trim();\r\n if (line === '' || attributePattern.test(line)) {\r\n // Skip empty lines and include attribute lines\r\n if (attributePattern.test(line)) {\r\n methodStart = i;\r\n }\r\n } else {\r\n // Stop when we hit a non-attribute, non-empty line\r\n break;\r\n }\r\n }\r\n \r\n // Find the method's opening brace and closing brace\r\n let braceCount = 0;\r\n let foundOpeningBrace = false;\r\n let methodEnd = -1;\r\n \r\n for (let i = methodStart; i < lines.length; i++) {\r\n const line = lines[i];\r\n for (const char of line) {\r\n if (char === '{') {\r\n braceCount++;\r\n foundOpeningBrace = true;\r\n } else if (char === '}') {\r\n braceCount--;\r\n if (foundOpeningBrace && braceCount === 0) {\r\n methodEnd = i;\r\n break;\r\n }\r\n }\r\n }\r\n if (methodEnd !== -1) break;\r\n }\r\n \r\n if (methodEnd === -1) {\r\n return null;\r\n }\r\n \r\n return { start: methodStart, end: methodEnd };\r\n}"]}
|
|
1
|
+
{"version":3,"file":"removeFailedTestMethods.js","sourceRoot":"","sources":["../../src/utils/removeFailedTestMethods.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\r\n\r\nimport { GenResult } from '../types/genResult';\r\nimport { BuildResult } from '../types/buildResult';\r\nimport { TestResult } from '../types/testResult';\r\nimport { LINESEPARATOR } from '../types/constants';\r\nimport { checkCodeSyntax } from '../analyze/checkCodeSyntax';\r\nimport { verifyGeneratedCode } from './verifyGeneratedCode';\r\nimport { writeTestCode } from './fileUtils';\r\n\r\ninterface TestMethodInfo {\r\n startLine: number;\r\n endLine: number;\r\n methodName: string;\r\n}\r\n\r\n/**\r\n * Remove lines at the given 0-based indices from `code`, then collapse\r\n * consecutive blank / whitespace-only lines down to a single blank line.\r\n */\r\nfunction removeLinesAndCleanup(code: string, linesToRemove: Set<number>): string {\r\n if (linesToRemove.size === 0) return code;\r\n\r\n const lines = code.split('\\n');\r\n const sorted = Array.from(linesToRemove).sort((a, b) => b - a);\r\n for (const idx of sorted) {\r\n lines.splice(idx, 1);\r\n }\r\n return lines.join('\\n').replace(/(\\n\\s*){3,}/g, '\\n\\n');\r\n}\r\n\r\nexport function removeFailedTests(filePath: string, failedTestNames: string[]) {\r\n try {\r\n if (!fs.existsSync(filePath)) {\r\n throw new Error(`File not exist ${filePath}`);\r\n }\r\n\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const lines = content.split(LINESEPARATOR);\r\n\r\n // get all test methods in the file\r\n const testMethods = findTestMethods(lines);\r\n\r\n // filter out methods that match the failed test names\r\n const methodsToRemove = testMethods.filter(method =>\r\n failedTestNames.includes(method.methodName)\r\n );\r\n\r\n if (methodsToRemove.length === 0) {\r\n console.log('Can not find any failed test methods to remove.');\r\n return;\r\n }\r\n\r\n // sort methods by start line in descending order\r\n // to avoid index issues when removing lines\r\n methodsToRemove.sort((a, b) => b.startLine - a.startLine);\r\n\r\n // delete the test methods from the lines\r\n let modifiedLines = [...lines];\r\n for (const method of methodsToRemove) {\r\n modifiedLines = removeTestMethod(modifiedLines, method);\r\n }\r\n\r\n // cleanup empty lines\r\n modifiedLines = cleanupEmptyLines(modifiedLines);\r\n\r\n\r\n const modifiedContent = modifiedLines.join('\\n');\r\n return modifiedContent;\r\n\r\n } catch (error) {\r\n console.error('Error removing failed tests:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * find all test methods in the file\r\n */\r\nfunction findTestMethods(lines: string[]): TestMethodInfo[] {\r\n const testMethods: TestMethodInfo[] = [];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n\r\n // find [TestMethod] attribute\r\n if (line === '[TestMethod]' || line.startsWith('[TestMethod(')) {\r\n // find the method definition starting from this line\r\n const methodInfo = findMethodDefinition(lines, i);\r\n if (methodInfo) {\r\n testMethods.push(methodInfo);\r\n }\r\n }\r\n }\r\n\r\n return testMethods;\r\n}\r\n\r\n/**\r\n * find the method definition based on the line number of [TestMethod]\r\n */\r\nfunction findMethodDefinition(lines: string[], testMethodLine: number): TestMethodInfo | null {\r\n let methodStartLine = testMethodLine;\r\n let methodName = '';\r\n let braceCount = 0;\r\n let methodFound = false;\r\n let methodEndLine = -1;\r\n\r\n // find the start of the method definition\r\n while (methodStartLine > 0 &&\r\n (lines[methodStartLine - 1].trim() === '' ||\r\n lines[methodStartLine - 1].trim().startsWith('['))) {\r\n methodStartLine--;\r\n }\r\n\r\n // find the method definition starting from the line after [TestMethod]\r\n for (let i = testMethodLine; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n\r\n // skip empty lines and section headers\r\n if (line === '' || line.startsWith('[')) {\r\n continue;\r\n }\r\n\r\n // find the method definition\r\n if (!methodFound && isMethodDefinition(line)) {\r\n methodName = extractMethodName(line);\r\n methodFound = true;\r\n\r\n // if the method is defined in a single line, we can directly set the end line\r\n const openBraces = (line.match(/{/g) || []).length;\r\n const closeBraces = (line.match(/}/g) || []).length;\r\n braceCount += openBraces - closeBraces;\r\n\r\n if (braceCount === 0 && openBraces > 0) {\r\n // single line method definition\r\n methodEndLine = i;\r\n break;\r\n }\r\n continue;\r\n }\r\n\r\n // if we have found the method definition, count braces\r\n if (methodFound) {\r\n const openBraces = (line.match(/{/g) || []).length;\r\n const closeBraces = (line.match(/}/g) || []).length;\r\n braceCount += openBraces - closeBraces;\r\n\r\n if (braceCount === 0) {\r\n methodEndLine = i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (methodFound && methodEndLine !== -1) {\r\n return {\r\n startLine: methodStartLine,\r\n endLine: methodEndLine,\r\n methodName: methodName\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * check if a line is a method definition\r\n */\r\nfunction isMethodDefinition(line: string): boolean {\r\n // simple regex to match method definitions\r\n // supports public, protected, internal, static, async, and method name with parameters\r\n const methodPattern = /^\\s*(public|function|protected|internal)?\\s*(static\\s+)?(async\\s+)?\\w+\\s+\\w+\\s*\\(/;\r\n return methodPattern.test(line);\r\n}\r\n\r\n/**\r\n * extract method name from a method definition line\r\n */\r\nexport function extractMethodName(line: string): string {\r\n const match = line.match(/\\b(\\w+)\\s*\\(/);\r\n return match ? match[1] : '';\r\n}\r\n\r\n/**\r\n * delete specific testt method block from lines\r\n */\r\nfunction removeTestMethod(lines: string[], method: TestMethodInfo): string[] {\r\n const newLines = [...lines];\r\n\r\n // delete methodn block(include [TestMethod] tag)\r\n newLines.splice(method.startLine, method.endLine - method.startLine + 1);\r\n\r\n return newLines;\r\n}\r\n\r\n/**\r\n * clean extra empty line, ensure only one empty line between methods\r\n */\r\nfunction cleanupEmptyLines(lines: string[]): string[] {\r\n const result: string[] = [];\r\n let emptyLineCount = 0;\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const isEmptyLine = line.trim() === '';\r\n\r\n if (isEmptyLine) {\r\n emptyLineCount++;\r\n // keep one empty line between methods\r\n if (emptyLineCount === 1) {\r\n result.push(line);\r\n }\r\n } else {\r\n emptyLineCount = 0;\r\n result.push(line);\r\n }\r\n }\r\n\r\n // remove trailing empty lines\r\n while (result.length > 0 && result[result.length - 1].trim() === '') {\r\n result.pop();\r\n }\r\n\r\n return result;\r\n}\r\n\r\n\r\nexport function removeFailedTestCasesInTestFile(vsTestRes: TestResult, testFilePath: string): void {\r\n const failedTestMethods = vsTestRes?.failedTests?.map(test => test.name) || [];\r\n const succeedTestCode = removeFailedTests(testFilePath, failedTestMethods);\r\n fs.writeFileSync(testFilePath, succeedTestCode, 'utf-8');\r\n console.log(`Removed failed test cases from file: ${testFilePath}`);\r\n}\r\n\r\n// const testCode = removeFailedTests(\"D:\\\\code\\\\CS.Service.Fundamental\\\\SharedSegments\\\\SharedSegments\\\\SharedSegments.Tests\\\\Workflows\\\\Overview\\\\HttpRequestParser\\\\Utils\\\\SqmidHelperTests.cs\", [\"GetSqmidFromCookie_InvalidBlisIdFormat_ReturnsEmptyString\", \"GetSqmidFromCookie_MissingUsrLocCookie_ReturnsEmptyString\"]);\r\n// console.log(testCode);\r\n\r\n/**\r\n * Try to remove failed test methods and verify if the remaining code is valid.\r\n * If testResult has errors, remove the failed test methods and check syntax.\r\n * If buildResult has errors, remove the test methods containing build errors and verify.\r\n */\r\nexport async function removeFailedTestMethods(\r\n testCode: string,\r\n testFilePath: string,\r\n testProjectPath: string,\r\n sourceCodePath: string,\r\n buildResult: BuildResult[] | null,\r\n testResult: TestResult | null,\r\n isVsPlugin: boolean,\r\n originalTestLength: number = 0\r\n): Promise<GenResult | null> {\r\n if (!testCode) {\r\n return null;\r\n }\r\n\r\n let updatedCode = testCode;\r\n\r\n // Case 1: Test errors - intelligently remove failed assertions or test methods\r\n if (testResult && testResult.failedTests && testResult.failedTests.length > 0) {\r\n console.log(\"Attempting to remove failed test methods or assertions...\");\r\n \r\n // Extract line numbers from failed test stack traces\r\n const errorLines: number[] = [];\r\n for (const failedTest of testResult.failedTests) {\r\n const lineMatches = failedTest.stackTrace.matchAll(/:line (\\d+)/g);\r\n for (const match of lineMatches) {\r\n errorLines.push(parseInt(match[1], 10));\r\n }\r\n }\r\n\r\n if (errorLines.length > 0) {\r\n updatedCode = removeFailedAssertionsOrMethods(updatedCode, errorLines);\r\n if (updatedCode !== testCode) {\r\n writeTestCode(updatedCode, testFilePath);\r\n \r\n const syntaxResult = await checkCodeSyntax(testFilePath);\r\n if (syntaxResult.success) {\r\n // Check if code length is greater than original\r\n if (originalTestLength > 0 && updatedCode.length <= originalTestLength) {\r\n console.error(\"Remaining code length is not greater than original test code length after removing failed tests.\");\r\n return null;\r\n }\r\n console.log(\"Successfully removed failed test assertions/methods, syntax check passed.\");\r\n return { success: true, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: null, testResult: null };\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Case 2: Build errors - remove test methods containing build errors\r\n if (buildResult && buildResult.length > 0) {\r\n console.log(\"Attempting to remove test methods with build errors...\");\r\n \r\n const errorLines = buildResult.map(err => err.line);\r\n updatedCode = removeTestMethodsByLines(updatedCode, errorLines);\r\n \r\n if (updatedCode !== testCode) {\r\n writeTestCode(updatedCode, testFilePath);\r\n \r\n const verifyResult = await verifyGeneratedCode(updatedCode, testProjectPath, testFilePath, isVsPlugin);\r\n \r\n if (verifyResult.success) {\r\n // Check if code length is greater than original\r\n if (originalTestLength > 0 && updatedCode.length <= originalTestLength) {\r\n console.error(\"Remaining code length is not greater than original test code length after removing build errors.\");\r\n return null;\r\n }\r\n console.log(\"Successfully removed test methods with build errors, verification passed.\");\r\n return { success: true, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: null, testResult: verifyResult.testResult };\r\n }\r\n \r\n // If still has build errors, return failure\r\n if (verifyResult.buildErrors && verifyResult.buildErrors.length > 0) {\r\n console.error(\"Still has build errors after removing test methods.\");\r\n return { success: false, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: verifyResult.buildErrors, testResult: null };\r\n }\r\n \r\n // If has test errors, try to remove failed test methods\r\n if (verifyResult.testResult && verifyResult.testResult.failedTests && verifyResult.testResult.failedTests.length > 0) {\r\n console.log(\"Build passed but has test errors, attempting to remove failed test methods...\");\r\n \r\n const testErrorLines: number[] = [];\r\n for (const failedTest of verifyResult.testResult.failedTests) {\r\n const lineMatches = failedTest.stackTrace.matchAll(/:line (\\d+)/g);\r\n for (const match of lineMatches) {\r\n testErrorLines.push(parseInt(match[1], 10));\r\n }\r\n }\r\n \r\n if (testErrorLines.length > 0) {\r\n const finalCode = removeFailedAssertionsOrMethods(updatedCode, testErrorLines);\r\n if (finalCode !== updatedCode) {\r\n writeTestCode(finalCode, testFilePath);\r\n \r\n const syntaxResult = await checkCodeSyntax(testFilePath);\r\n if (syntaxResult.success) {\r\n // Check if code length is greater than original\r\n if (originalTestLength > 0 && finalCode.length <= originalTestLength) {\r\n console.error(\"Remaining code length is not greater than original test code length after removing failed tests.\");\r\n return null;\r\n }\r\n console.log(\"Successfully removed failed test methods after build fix, syntax check passed.\");\r\n return { success: true, testFilePath, testProjectPath, codeFilePath: sourceCodePath, buildResult: null, testResult: null };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Remove failed assertions or entire test methods based on the error lines.\r\n * Strategy:\r\n * - If only one assert in the method, remove the entire method\r\n * - If multiple asserts and the failed assert has no other asserts above it, remove the entire method\r\n * - If multiple asserts and there are asserts above the failed one, only remove from failed assert to method end\r\n */\r\nfunction removeFailedAssertionsOrMethods(code: string, errorLines: number[]): string {\r\n const lines = code.split('\\n');\r\n const linesToRemove = new Set<number>();\r\n \r\n // Process each error line\r\n for (const errorLine of errorLines) {\r\n const targetLineIndex = errorLine - 1; // Convert to 0-based index\r\n \r\n // Find the test method that contains this error line\r\n const methodRange = findTestMethodRangeByBrace(lines, targetLineIndex);\r\n if (!methodRange) {\r\n continue;\r\n }\r\n \r\n // Find all assert lines in this method\r\n const assertLines = findAssertLinesInRange(lines, methodRange.start, methodRange.end);\r\n \r\n if (assertLines.length <= 1) {\r\n // Only one assert (or none), remove the entire method\r\n for (let i = methodRange.start; i <= methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n } else {\r\n // Multiple asserts - check if there are asserts above the failed line\r\n const assertsAbove = assertLines.filter(line => line < targetLineIndex);\r\n \r\n if (assertsAbove.length === 0) {\r\n // No asserts above the failed line, remove the entire method\r\n for (let i = methodRange.start; i <= methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n } else {\r\n // There are asserts above, only remove from the failed assert line to method end\r\n // Find the start of the failed assert statement (it might span multiple lines)\r\n let assertStartLine = findAssertStatementStart(lines, targetLineIndex);\r\n \r\n // Also include comments and empty lines above the assert\r\n assertStartLine = findCodeBlockStart(lines, assertStartLine, methodRange.start);\r\n \r\n // Remove from assert start to method end (but keep the closing brace on a new line)\r\n for (let i = assertStartLine; i < methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n }\r\n }\r\n }\r\n \r\n if (linesToRemove.size === 0) {\r\n return code;\r\n }\r\n \r\n return removeLinesAndCleanup(code, linesToRemove);\r\n}\r\n\r\n/**\r\n * Find all assert statement lines within the given line range.\r\n * Supports different test frameworks: MSTest, NUnit, xUnit\r\n */\r\nfunction findAssertLinesInRange(lines: string[], startLine: number, endLine: number): number[] {\r\n const assertLines: number[] = [];\r\n \r\n // Patterns for different test frameworks\r\n // MSTest: Assert.AreEqual, Assert.IsTrue, Assert.IsFalse, Assert.IsNull, Assert.IsNotNull, Assert.ThrowsException, etc.\r\n // NUnit: Assert.AreEqual, Assert.That, Assert.IsTrue, Assert.Throws, etc.\r\n // xUnit: Assert.Equal, Assert.True, Assert.False, Assert.Null, Assert.NotNull, Assert.Throws, etc.\r\n // Also support FluentAssertions: .Should()\r\n const assertPatterns = [\r\n /\\bAssert\\s*\\./i, // Assert.xxx (MSTest, NUnit, xUnit)\r\n /\\bStringAssert\\s*\\./i, // StringAssert.xxx (MSTest)\r\n /\\bCollectionAssert\\s*\\./i, // CollectionAssert.xxx (MSTest)\r\n /\\.Should\\s*\\(/i, // FluentAssertions: xxx.Should()\r\n /\\.ShouldBe\\s*\\(/i, // Shouldly: xxx.ShouldBe()\r\n /\\.ShouldEqual\\s*\\(/i, // Shouldly variants\r\n /\\bExpect\\s*\\(/i, // NUnit Expect\r\n ];\r\n \r\n for (let i = startLine; i <= endLine; i++) {\r\n const line = lines[i];\r\n for (const pattern of assertPatterns) {\r\n if (pattern.test(line)) {\r\n assertLines.push(i);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n return assertLines;\r\n}\r\n\r\n/**\r\n * Find the start line of an assert statement (it may span multiple lines).\r\n * Searches backwards to find the actual start of the statement.\r\n */\r\nfunction findAssertStatementStart(lines: string[], assertLine: number): number {\r\n const assertPatterns = [\r\n /\\bAssert\\s*\\./i,\r\n /\\bStringAssert\\s*\\./i,\r\n /\\bCollectionAssert\\s*\\./i,\r\n /\\.Should\\s*\\(/i,\r\n /\\.ShouldBe\\s*\\(/i,\r\n /\\.ShouldEqual\\s*\\(/i,\r\n /\\bExpect\\s*\\(/i,\r\n ];\r\n \r\n // Check if current line contains an assert pattern\r\n const currentLine = lines[assertLine];\r\n for (const pattern of assertPatterns) {\r\n if (pattern.test(currentLine)) {\r\n return assertLine; // Assert starts on this line\r\n }\r\n }\r\n \r\n // If not found on current line, search backwards for the statement start\r\n // This handles cases where the assert call spans multiple lines\r\n for (let i = assertLine - 1; i >= 0; i--) {\r\n const line = lines[i];\r\n for (const pattern of assertPatterns) {\r\n if (pattern.test(line)) {\r\n return i;\r\n }\r\n }\r\n // If we hit an empty line or a line ending with semicolon or opening brace, stop\r\n const trimmedLine = line.trim();\r\n if (trimmedLine === '' || trimmedLine.endsWith(';') || trimmedLine.endsWith('{')) {\r\n break;\r\n }\r\n }\r\n \r\n return assertLine; // Fallback to the original line\r\n}\r\n\r\n/**\r\n * Find the start of a code block including comments and empty lines above it.\r\n * Searches backwards from the given line to include preceding comments and empty lines.\r\n */\r\nfunction findCodeBlockStart(lines: string[], startLine: number, minLine: number): number {\r\n let result = startLine;\r\n \r\n // Comment patterns\r\n const singleLineCommentPattern = /^\\s*\\/\\//;\r\n const blockCommentEndPattern = /\\*\\/\\s*$/;\r\n const blockCommentStartPattern = /^\\s*\\/\\*/;\r\n \r\n for (let i = startLine - 1; i >= minLine; i--) {\r\n const line = lines[i];\r\n const trimmedLine = line.trim();\r\n \r\n if (trimmedLine === '') {\r\n // Empty line, include it\r\n result = i;\r\n } else if (singleLineCommentPattern.test(line)) {\r\n // Single line comment (// comment), include it\r\n result = i;\r\n } else if (blockCommentEndPattern.test(trimmedLine)) {\r\n // End of block comment, search backwards for the start\r\n result = i;\r\n for (let j = i; j >= minLine; j--) {\r\n result = j;\r\n if (blockCommentStartPattern.test(lines[j])) {\r\n break;\r\n }\r\n }\r\n i = result; // Continue from the block comment start\r\n } else {\r\n // Hit actual code, stop\r\n break;\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Remove test methods that contain the specified line numbers.\r\n * Finds the test method boundaries and removes the entire method.\r\n */\r\nfunction removeTestMethodsByLines(code: string, errorLines: number[]): string {\r\n const lines = code.split('\\n');\r\n const linesToRemove = new Set<number>();\r\n \r\n for (const errorLine of errorLines) {\r\n // Find the test method that contains this error line\r\n const methodRange = findTestMethodRangeByBrace(lines, errorLine - 1); // Convert to 0-based index\r\n if (methodRange) {\r\n for (let i = methodRange.start; i <= methodRange.end; i++) {\r\n linesToRemove.add(i);\r\n }\r\n }\r\n }\r\n \r\n if (linesToRemove.size === 0) {\r\n return code;\r\n }\r\n \r\n return removeLinesAndCleanup(code, linesToRemove);\r\n}\r\n\r\n/**\r\n * Find the start and end line indices of the test method containing the given line.\r\n * Includes all attributes above the test method attribute (e.g., [DataRow], [Category], etc.)\r\n */\r\nexport function findTestMethodRangeByBrace(lines: string[], targetLineIndex: number): { start: number, end: number } | null {\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 // Pattern to match any C# attribute\r\n const attributePattern = /^\\s*\\[.+\\]\\s*$/;\r\n \r\n // Search backwards to find the test method attribute\r\n let testAttributeLine = -1;\r\n for (let i = targetLineIndex; 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 testAttributeLine = i;\r\n break;\r\n }\r\n }\r\n if (testAttributeLine !== -1) break;\r\n }\r\n \r\n if (testAttributeLine === -1) {\r\n return null; // Not inside a test method\r\n }\r\n \r\n // Search upward from test attribute to include all consecutive attributes above it\r\n // (e.g., [DataRow], [Category], [Description], etc.)\r\n let methodStart = testAttributeLine;\r\n for (let i = testAttributeLine - 1; i >= 0; i--) {\r\n const line = lines[i].trim();\r\n if (line === '' || attributePattern.test(line)) {\r\n // Skip empty lines and include attribute lines\r\n if (attributePattern.test(line)) {\r\n methodStart = i;\r\n }\r\n } else {\r\n // Stop when we hit a non-attribute, non-empty line\r\n break;\r\n }\r\n }\r\n \r\n // Find the method's opening brace and closing brace\r\n let braceCount = 0;\r\n let foundOpeningBrace = false;\r\n let methodEnd = -1;\r\n \r\n for (let i = methodStart; i < lines.length; i++) {\r\n const line = lines[i];\r\n for (const char of line) {\r\n if (char === '{') {\r\n braceCount++;\r\n foundOpeningBrace = true;\r\n } else if (char === '}') {\r\n braceCount--;\r\n if (foundOpeningBrace && braceCount === 0) {\r\n methodEnd = i;\r\n break;\r\n }\r\n }\r\n }\r\n if (methodEnd !== -1) break;\r\n }\r\n \r\n if (methodEnd === -1) {\r\n return null;\r\n }\r\n \r\n return { start: methodStart, end: methodEnd };\r\n}"]}
|
|
@@ -1 +1,6 @@
|
|
|
1
1
|
export declare function writeGenCode(sourceCodePath: string, genCode: string, genCnt: number, sourceCodeProjectPath: string): void;
|
|
2
|
+
/**
|
|
3
|
+
* Write the AI raw response code to atmpCache/aiRawResponses for debugging / auditing.
|
|
4
|
+
* File name: {testFileBaseName}_{timestamp}.cs
|
|
5
|
+
*/
|
|
6
|
+
export declare function writeAIRawCode(aiCode: string, testFilePath?: string): void;
|
|
@@ -34,11 +34,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.writeGenCode = writeGenCode;
|
|
37
|
+
exports.writeAIRawCode = writeAIRawCode;
|
|
37
38
|
const path = __importStar(require("path"));
|
|
38
39
|
const fs = __importStar(require("fs"));
|
|
39
40
|
const getOrCreateDir_1 = require("./getOrCreateDir");
|
|
40
41
|
const fileUtils_1 = require("./fileUtils");
|
|
41
42
|
const TESTFILEDIR = './testFiles';
|
|
43
|
+
const AI_RAW_RESPONSES_DIR = './aiRawResponses';
|
|
42
44
|
function writeGenCode(sourceCodePath, genCode, genCnt, sourceCodeProjectPath) {
|
|
43
45
|
const sourceFileName = path.basename(sourceCodePath, '.cs');
|
|
44
46
|
let testFileName = `${sourceFileName}Tests${genCnt}.cs`;
|
|
@@ -56,6 +58,19 @@ function writeGenCode(sourceCodePath, genCode, genCnt, sourceCodeProjectPath) {
|
|
|
56
58
|
(0, fileUtils_1.writeTestCode)(genCode, testFilePath);
|
|
57
59
|
console.log(`Generated code written to: ${testFilePath}`);
|
|
58
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Write the AI raw response code to atmpCache/aiRawResponses for debugging / auditing.
|
|
63
|
+
* File name: {testFileBaseName}_{timestamp}.cs
|
|
64
|
+
*/
|
|
65
|
+
function writeAIRawCode(aiCode, testFilePath) {
|
|
66
|
+
const baseName = testFilePath ? path.basename(testFilePath, '.cs') : 'unknown';
|
|
67
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
68
|
+
const fileName = `${baseName}_${timestamp}.cs`;
|
|
69
|
+
const dir = (0, getOrCreateDir_1.getTmpCacheDir)(AI_RAW_RESPONSES_DIR);
|
|
70
|
+
const filePath = path.join(dir, fileName);
|
|
71
|
+
(0, fileUtils_1.writeTestCode)(aiCode, filePath);
|
|
72
|
+
console.log(`AI raw code written to: ${filePath}`);
|
|
73
|
+
}
|
|
59
74
|
// writeGenCode("Q:\\MyProject\\TestTestReport\\TestTestReport\\TestFolder\\Summary.cs",
|
|
60
75
|
// "public class SummaryTests { }",
|
|
61
76
|
// 2,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeGenCode.js","sourceRoot":"","sources":["../../src/utils/writeGenCode.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"writeGenCode.js","sourceRoot":"","sources":["../../src/utils/writeGenCode.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,oCAmBC;AAMD,wCAQC;AA1CD,2CAA6B;AAC7B,uCAAyB;AAEzB,qDAAkD;AAClD,2CAA4C;AAE5C,MAAM,WAAW,GAAG,aAAa,CAAC;AAClC,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEhD,SAAgB,YAAY,CAAC,cAAsB,EAAE,OAAe,EAAE,MAAc,EAAE,qBAA6B;IAC/G,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC5D,IAAI,YAAY,GAAG,GAAG,cAAc,QAAQ,MAAM,KAAK,CAAC;IACxD,IAAI,WAAW,GAAG,IAAA,+BAAc,EAAC,WAAW,CAAC,CAAC;IAE9C,IAAI,qBAAqB,IAAI,EAAE,CAAC,UAAU,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAChE,gDAAgD;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACvD,8DAA8D;QAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAC/D,0BAA0B;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5C,WAAW,GAAG,IAAA,+BAAc,EAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAE1D,IAAA,yBAAa,EAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,MAAc,EAAE,YAAqB;IAChE,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,SAAS,KAAK,CAAC;IAC/C,MAAM,GAAG,GAAG,IAAA,+BAAc,EAAC,oBAAoB,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,IAAA,yBAAa,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,yFAAyF;AACzF,uCAAuC;AACvC,UAAU;AACV,gFAAgF","sourcesContent":["import * as path from 'path';\r\nimport * as fs from 'fs';\r\n\r\nimport { getTmpCacheDir } from './getOrCreateDir';\r\nimport { writeTestCode } from './fileUtils';\r\n\r\nconst TESTFILEDIR = './testFiles';\r\nconst AI_RAW_RESPONSES_DIR = './aiRawResponses';\r\n\r\nexport function writeGenCode(sourceCodePath: string, genCode: string, genCnt: number, sourceCodeProjectPath: string) {\r\n const sourceFileName = path.basename(sourceCodePath, '.cs');\r\n let testFileName = `${sourceFileName}Tests${genCnt}.cs`;\r\n let testFileDir = getTmpCacheDir(TESTFILEDIR);\r\n\r\n if (sourceCodeProjectPath && fs.existsSync(sourceCodeProjectPath)) {\r\n // Get the directory containing the .csproj file\r\n const projectDir = path.dirname(sourceCodeProjectPath);\r\n // Get the relative path from project directory to source file\r\n const relativePath = path.relative(projectDir, sourceCodePath);\r\n // Parse the relative path\r\n const parsedPath = path.parse(relativePath);\r\n testFileDir = getTmpCacheDir(path.join(TESTFILEDIR, parsedPath.dir));\r\n }\r\n \r\n const testFilePath = path.join(testFileDir, testFileName);\r\n \r\n writeTestCode(genCode, testFilePath);\r\n console.log(`Generated code written to: ${testFilePath}`);\r\n}\r\n\r\n/**\r\n * Write the AI raw response code to atmpCache/aiRawResponses for debugging / auditing.\r\n * File name: {testFileBaseName}_{timestamp}.cs\r\n */\r\nexport function writeAIRawCode(aiCode: string, testFilePath?: string): void {\r\n const baseName = testFilePath ? path.basename(testFilePath, '.cs') : 'unknown';\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\r\n const fileName = `${baseName}_${timestamp}.cs`;\r\n const dir = getTmpCacheDir(AI_RAW_RESPONSES_DIR);\r\n const filePath = path.join(dir, fileName);\r\n writeTestCode(aiCode, filePath);\r\n console.log(`AI raw code written to: ${filePath}`);\r\n}\r\n\r\n// writeGenCode(\"Q:\\\\MyProject\\\\TestTestReport\\\\TestTestReport\\\\TestFolder\\\\Summary.cs\",\r\n// \"public class SummaryTests { }\",\r\n// 2,\r\n// \"Q:\\\\MyProject\\\\TestTestReport\\\\TestTestReport\\\\TestTestReport.csproj\");"]}
|