- 新增 jsp-extractor/report/method-extractor/fix-prompt/registry/provider-chat/import-service/yaml-parser 测试 - .vscode-test.mjs 加 srcDir+coverage,package.json 加 test:coverage,产出 tests/coverage/(html) - 修复 method-extractor java fallback 取错捕获组、mockDocument.getText 忽略 range - 更新 tests/test-cases.md(24 文件 179 条)与 test-execution-log.md(覆盖率记录)
130 lines
4.7 KiB
TypeScript
130 lines
4.7 KiB
TypeScript
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);
|
|
});
|
|
});
|