import * as assert from 'assert'; import * as vscode from 'vscode'; import { ESLintAdapter } from '../src/adapters/eslint'; import { fixDiagnostic } from '../src/fix/fixEngine'; suite('FixEngine Tests', () => { test('ESLint adapter attaches fix object for autofixable issues', async () => { const adapter = new ESLintAdapter(); if (!adapter.isAvailable()) { return; } const doc = await vscode.workspace.openTextDocument({ content: 'var name = "Hi " + user;\n', language: 'javascript', }); const result = await adapter.check(doc, __dirname); assert.strictEqual(result.status, 'ok'); const fixable = result.diagnostics.filter(d => d.fix); assert.ok(fixable.length >= 1, 'prefer-template/no-var should be autofixable'); const prefer = fixable.find(d => d.ruleId === 'eslint:prefer-template'); assert.ok(prefer, 'expected prefer-template diagnostic'); assert.ok(prefer!.fix!.range[0] < prefer!.fix!.range[1]); assert.ok(prefer!.fix!.text.length > 0); }); test('fixDiagnostic multi-round convergence produces applied fixes', async () => { const adapter = new ESLintAdapter(); if (!adapter.isAvailable()) { return; } const doc = await vscode.workspace.openTextDocument({ content: 'var name = "Hi " + user;\n', language: 'javascript', }); const result = await adapter.check(doc, __dirname); const prefer = result.diagnostics.find(d => d.ruleId === 'eslint:prefer-template' && d.fix); if (!prefer) { return; } const fixResult = await fixDiagnostic(doc, __dirname, adapter, prefer, 3); if (fixResult.success) { assert.ok(fixResult.appliedFixes.length >= 1); } else { assert.ok(fixResult.message === 'no-active-editor' || fixResult.message === 'not-autofixable', `unexpected failure: ${fixResult.message}`); } }); test('fixDiagnostic returns not-autofixable for non-fixable rule', async () => { const adapter = new ESLintAdapter(); if (!adapter.isAvailable()) { return; } const doc = await vscode.workspace.openTextDocument({ content: 'function unused(a, b) { return a; }\n', language: 'javascript', }); const result = await adapter.check(doc, __dirname); const unused = result.diagnostics.find(d => d.ruleId === 'eslint:no-unused-vars'); if (!unused) { return; } assert.ok(!unused.fix, 'no-unused-vars is not autofixable'); const fixResult = await fixDiagnostic(doc, __dirname, adapter, unused, 3); assert.strictEqual(fixResult.success, false); assert.strictEqual(fixResult.message, 'not-autofixable'); }); test('fixDiagnostic no-change returns no-change', async () => { const adapter = new ESLintAdapter(); if (!adapter.isAvailable()) { return; } const doc = await vscode.workspace.openTextDocument({ content: 'const ok = 1;\n', language: 'javascript', }); const result = await adapter.check(doc, __dirname); const anyDiag = result.diagnostics.find(d => d.ruleId === 'eslint:no-extra-semi'); if (anyDiag) { const fixResult = await fixDiagnostic(doc, __dirname, adapter, anyDiag, 3); assert.ok(fixResult.success === false); } }); test('fixDiagnostic fixes only the targeted issue, not adjacent same-rule instance', async () => { const adapter = new ESLintAdapter(); if (!adapter.isAvailable()) { return; } const doc = await vscode.workspace.openTextDocument({ content: 'var a = 1;\nvar b = 2;\n', language: 'javascript', }); const result = await adapter.check(doc, __dirname); const first = result.diagnostics.find(d => d.ruleId === 'eslint:no-var' && d.fix && d.range.start.line === 0); if (!first) { return; } const fixResult = await fixDiagnostic(doc, __dirname, adapter, first, 3); if (fixResult.success) { assert.strictEqual(fixResult.appliedFixes.length, 1); } else { assert.ok(fixResult.message === 'not-autofixable' || fixResult.message === 'no-change', `unexpected failure: ${fixResult.message}`); } }); });