From 97362ca4b563b822c500d4d15ec567462265ecd7 Mon Sep 17 00:00:00 2001 From: Jag Jayaprakash Date: Wed, 14 Aug 2024 15:09:40 -0700 Subject: [PATCH] NEW (Extension) @W-16442046@ Apex guru fixer logic - part 3 --- src/apexguru/apex-guru-service.ts | 7 +- src/lib/diagnostics.ts | 8 +- src/lib/fixer.ts | 3 +- .../suite/apexguru/apex-guru-service.test.ts | 1 + src/test/suite/fixer.test.ts | 126 +++++++++++++++++- 5 files changed, 134 insertions(+), 11 deletions(-) diff --git a/src/apexguru/apex-guru-service.ts b/src/apexguru/apex-guru-service.ts index 1cd6fb2..5eb4b1b 100644 --- a/src/apexguru/apex-guru-service.ts +++ b/src/apexguru/apex-guru-service.ts @@ -128,15 +128,16 @@ export function transformStringToRuleResult(fileName: string, jsonString: string }; reports.forEach(parsed => { - const encodedCodeBefore = parsed.properties.find((prop: ApexGuruProperty) => prop.name === 'code_before')?.value; - const encodedCodeAfter = parsed.properties.find((prop: ApexGuruProperty) => prop.name === 'code_after')?.value; + const encodedCodeBefore = parsed.properties.find((prop: ApexGuruProperty) => prop.name === 'code_before')?.value ?? ''; + const encodedCodeAfter = parsed.properties.find((prop: ApexGuruProperty) => prop.name === 'code_after')?.value ?? ''; + const lineNumber = parseInt(parsed.properties.find((prop: ApexGuruProperty) => prop.name === 'line_number')?.value); const violation: ApexGuruViolation = { ruleName: parsed.type, message: parsed.value, severity: 1, category: parsed.type, // Replace with actual category if available - line: parseInt(parsed.properties.find((prop: ApexGuruProperty) => prop.name === 'line_number')?.value), + line: lineNumber, column: 1, currentCode: Buffer.from(encodedCodeBefore, 'base64').toString('utf8'), suggestedCode: Buffer.from(encodedCodeAfter, 'base64').toString('utf8'), diff --git a/src/lib/diagnostics.ts b/src/lib/diagnostics.ts index 61f0ff4..461c665 100644 --- a/src/lib/diagnostics.ts +++ b/src/lib/diagnostics.ts @@ -95,12 +95,12 @@ export class DiagnosticManager { if (apexGuruViolation.suggestedCode?.trim()) { diagnostic.relatedInformation = [ new vscode.DiagnosticRelatedInformation( - new vscode.Location(vscode.Uri.parse('Code Before'), range), - `Code before: ${apexGuruViolation.currentCode}` + new vscode.Location(vscode.Uri.parse('***Current Code***'), range), + `${apexGuruViolation.currentCode}` ), new vscode.DiagnosticRelatedInformation( - new vscode.Location(vscode.Uri.parse('Code After'), range), - `Code after: ${apexGuruViolation.suggestedCode}` + new vscode.Location(vscode.Uri.parse('***Apex Guru Suggestions***'), range), + `${apexGuruViolation.suggestedCode}` ) ]; } diff --git a/src/lib/fixer.ts b/src/lib/fixer.ts index 1a2024f..00ed8b4 100644 --- a/src/lib/fixer.ts +++ b/src/lib/fixer.ts @@ -117,7 +117,8 @@ export class _ApexGuruFixGenerator extends FixGenerator { const edit = new vscode.WorkspaceEdit(); const range = this.diagnostic.range; // Assuming the range is the location of the existing code in the document - edit.insert(document.uri, range.start, suggestedCode + '\n'); + const oneLineAbove = new vscode.Position(range.start.line > 1 ? range.start.line - 1 : 0, range.start.character); + edit.insert(document.uri, oneLineAbove, suggestedCode + '\n'); // Assign the edit to the action action.edit = edit; diff --git a/src/test/suite/apexguru/apex-guru-service.test.ts b/src/test/suite/apexguru/apex-guru-service.test.ts index 446131d..770274a 100644 --- a/src/test/suite/apexguru/apex-guru-service.test.ts +++ b/src/test/suite/apexguru/apex-guru-service.test.ts @@ -176,6 +176,7 @@ suite('Apex Guru Test Suite', () => { category: 'BestPractices', line: 10, column: 1, + currentCode: '', suggestedCode: 'System.out.println("Hello World");' }] }); diff --git a/src/test/suite/fixer.test.ts b/src/test/suite/fixer.test.ts index 0e22e42..7f72999 100644 --- a/src/test/suite/fixer.test.ts +++ b/src/test/suite/fixer.test.ts @@ -7,9 +7,7 @@ import * as vscode from 'vscode'; import {expect} from 'chai'; import path = require('path'); -import Sinon = require('sinon'); -import {messages} from '../../lib/messages'; -import {_NoOpFixGenerator, _PmdFixGenerator} from '../../lib/fixer'; +import {_NoOpFixGenerator, _PmdFixGenerator, _ApexGuruFixGenerator} from '../../lib/fixer'; suite('fixer.ts', () => { // Note: __dirname is used here because it's consistent across file systems. @@ -489,4 +487,126 @@ suite('fixer.ts', () => { }); }); }); + suite('_ApexGuruFixGenerator', () => { + const fileUri = vscode.Uri.file(path.join(codeFixturesPath, 'MyClass1.cls')); + suite('#generateFixes()', () => { + const processedLines = new Set(); + const fileUri = vscode.Uri.file(path.join(codeFixturesPath, 'MyClass1.cls')); + + let doc: vscode.TextDocument; + // Load the document and store its starting contents. + setup(async () => { + doc = await vscode.workspace.openTextDocument(fileUri); + await vscode.window.showTextDocument(doc); + }); + + test('Should generate a suppression fix if line is not processed', async () => { + // Create a fake diagnostic. + const diag = new vscode.Diagnostic( + new vscode.Range( + new vscode.Position(7, 4), + new vscode.Position(7, 10) + ), + 'some message', + vscode.DiagnosticSeverity.Warning + ); + diag.relatedInformation = [ + new vscode.DiagnosticRelatedInformation( + new vscode.Location(fileUri, new vscode.Position(0, 0)), + 'current code' + ), + new vscode.DiagnosticRelatedInformation( + new vscode.Location(fileUri, new vscode.Position(0, 0)), + 'apex guru suggested code' + ) + ]; + + // Instantiate the fixer. + const fixGenerator: _ApexGuruFixGenerator = new _ApexGuruFixGenerator(doc, diag); + + // Generate fixes. + const fixes: vscode.CodeAction[] = fixGenerator.generateFixes(processedLines, doc, diag); + + // Validate results. + expect(fixes).to.have.lengthOf(1, 'One fix should be offered'); + const fix = fixes[0].edit.get(fileUri)[0]; + expect(fix.newText).to.equal('apex guru suggested code\n', 'The suppression code should match the suggestion'); + expect(fix.range.start.line).to.equal(6, 'The suppression should be added one line above the diagnostic line'); + }); + + test('Should not generate a suppression fix if line is already processed', async () => { + processedLines.add(7); + + // Create a fake diagnostic. + const diag = new vscode.Diagnostic( + new vscode.Range( + new vscode.Position(7, 4), + new vscode.Position(7, 10) + ), + 'This message is unimportant', + vscode.DiagnosticSeverity.Warning + ); + diag.relatedInformation = [ + new vscode.DiagnosticRelatedInformation( + new vscode.Location(fileUri, new vscode.Position(0, 0)), + 'current code' + ), + new vscode.DiagnosticRelatedInformation( + new vscode.Location(fileUri, new vscode.Position(0, 0)), + 'apex guru suggested code' + ) + ]; + + // Instantiate the fixer. + const fixGenerator: _ApexGuruFixGenerator = new _ApexGuruFixGenerator(doc, diag); + + // Generate fixes. + const fixes: vscode.CodeAction[] = fixGenerator.generateFixes(processedLines, doc, diag); + + // Validate results. + expect(fixes).to.have.lengthOf(0, 'No fix should be offered if the line is already processed'); + }); + }); + + suite('#generateApexGuruSuppresssion()', () => { + let doc: vscode.TextDocument; + // Load the document and store its starting contents. + setup(async () => { + doc = await vscode.workspace.openTextDocument(fileUri); + await vscode.window.showTextDocument(doc); + }); + + test('Should generate the correct ApexGuru suppression code action', async () => { + // Create a fake diagnostic. + const diag = new vscode.Diagnostic( + new vscode.Range( + new vscode.Position(7, 4), + new vscode.Position(7, 10) + ), + 'Some message', + vscode.DiagnosticSeverity.Warning + ); + diag.relatedInformation = [ + new vscode.DiagnosticRelatedInformation( + new vscode.Location(fileUri, new vscode.Position(0, 0)), + 'Some other information' + ), + new vscode.DiagnosticRelatedInformation( + new vscode.Location(fileUri, new vscode.Position(0, 0)), + 'apex guru suggested code' + ) + ]; + + // Instantiate the fixer. + const fixGenerator: _ApexGuruFixGenerator = new _ApexGuruFixGenerator(doc, diag); + + // Generate the suppression code action. + const fix = fixGenerator.generateApexGuruSuppresssion(doc); + + // Validate results. + expect(fix.edit.get(fileUri)[0].newText).to.equal('apex guru suggested code\n', 'The suppression code should match the suggestion'); + expect(fix.edit.get(fileUri)[0].range.start.line).to.equal(6, 'The suppression should be added one line above the diagnostic line'); + }); + }); + }); });