import * as assert from 'assert'; import * as vscode from 'vscode'; import { mockDocument } from '../src/utils/mockDocument'; import { extractMethodScope, getMethodSymbols } from '../src/scope/method-extractor'; suite('MethodExtractor Tests', () => { test('fallback regex finds js function declarations and arrow functions', async () => { const code = [ 'function foo() { return 1; }', 'const bar = () => 2;', 'const baz = function(x) { return x; };', ].join('\n'); const doc = mockDocument(code, 'javascript'); const symbols = await getMethodSymbols(doc); const names = symbols.map(s => s.name); assert.ok(names.includes('foo')); assert.ok(names.includes('bar')); assert.ok(names.includes('baz')); }); test('fallback regex finds java methods', async () => { const code = 'public class A {\n public void run() {}\n private int calc(int x) { return x; }\n}'; const doc = mockDocument(code, 'java'); const symbols = await getMethodSymbols(doc); const names = symbols.map(s => s.name); assert.ok(names.includes('run')); assert.ok(names.includes('calc')); }); test('fallback regex returns empty for unsupported language', async () => { const doc = mockDocument('print("hi")', 'python'); const symbols = await getMethodSymbols(doc); assert.strictEqual(symbols.length, 0); }); test('extractMethodScope returns code, signature and callers', async () => { const code = [ 'function processOrder(items) {', ' var total = 0;', ' for (var i = 0; i < items.length; i++) {', ' total += items[i].amount;', ' }', ' return total;', '}', '', 'function orderValidate(record) {', ' return processOrder(record.items);', '}', ].join('\n'); const doc = mockDocument(code, 'javascript'); const scope = await extractMethodScope(doc, new vscode.Range(0, 0, 0, 0)); assert.ok(scope); assert.strictEqual(scope!.name, 'processOrder'); assert.match(scope!.code, /function processOrder/); assert.deepStrictEqual(scope!.callees, []); assert.ok(scope!.callers.includes('orderValidate')); assert.match(scope!.signature, /processOrder/); }); test('extractMethodScope identifies callees', async () => { const code = [ 'function helper() { return 1; }', 'function main() {', ' return helper();', '}', ].join('\n'); const doc = mockDocument(code, 'javascript'); const scope = await extractMethodScope(doc, new vscode.Range(1, 0, 1, 0)); assert.ok(scope); assert.strictEqual(scope!.name, 'main'); assert.deepStrictEqual(scope!.callees, ['helper']); }); test('expandToMethodBody ignores braces inside strings and comments', async () => { const code = [ 'function tricky() {', ' const s = "}";', ' // }', ' return s;', '}', ].join('\n'); const doc = mockDocument(code, 'javascript'); const scope = await extractMethodScope(doc, new vscode.Range(0, 0, 0, 0)); assert.ok(scope); assert.strictEqual(scope!.range.end.line, 4); assert.match(scope!.code, /tricky/); }); test('extractSignature strips leading comments', async () => { const code = [ '// legacy handler', '/* block */', 'function handle(input) {', ' return input;', '}', ].join('\n'); const doc = mockDocument(code, 'javascript'); const scope = await extractMethodScope(doc, new vscode.Range(2, 0, 2, 0)); assert.ok(scope); assert.match(scope!.signature, /handle/); assert.ok(!scope!.signature.includes('//')); }); test('inferRole maps getter, process and generic names', async () => { const code = [ 'function getUser() { return {}; }', 'function processOrder() { return 1; }', 'function doThing() { return 1; }', ].join('\n'); const doc = mockDocument(code, 'javascript'); const getter = await extractMethodScope(doc, new vscode.Range(0, 0, 0, 0)); assert.ok(getter); assert.strictEqual(getter!.name, 'getUser'); assert.strictEqual(getter!.role, '属性访问器'); const proc = await extractMethodScope(doc, new vscode.Range(1, 0, 1, 0)); assert.ok(proc); assert.strictEqual(proc!.name, 'processOrder'); assert.strictEqual(proc!.role, '流程处理'); const generic = await extractMethodScope(doc, new vscode.Range(2, 0, 2, 0)); assert.ok(generic); assert.strictEqual(generic!.role, '通用方法'); }); test('extractMethodScope returns null when range matches no method', async () => { const doc = mockDocument('var x = 1;\n', 'javascript'); const scope = await extractMethodScope(doc, new vscode.Range(0, 0, 0, 0)); assert.strictEqual(scope, null); }); });