GitNexus/gitnexus/test/integration/doc-comment-description-e2e.test.ts

94 lines
3.3 KiB
TypeScript

/**
* End-to-end coverage for issue #2270: a leading doc comment must survive the
* full parse pipeline into the node's `description` property (the field the
* embedding metadata header reads for semantic search). The unit tests stop at
* the `descriptionExtractor` hook; this exercises the real worker pipeline and
* the highest-value case — an EXPORTED TS function, whose JSDoc precedes the
* wrapping `export_statement` (PR #2286 review fix).
*/
import { describe, expect, it } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { runPipelineFromRepo } from './resolvers/helpers.js';
import type { PipelineResult } from '../../src/types/pipeline.js';
import { isLanguageAvailable } from '../../src/core/tree-sitter/parser-loader.js';
import { SupportedLanguages } from '../../src/config/supported-languages.js';
function createTsRepo(): string {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'doc-desc-e2e-'));
fs.writeFileSync(
path.join(dir, 'package.json'),
JSON.stringify({ name: 'doc-desc-e2e', version: '1.0.0' }),
);
fs.writeFileSync(
path.join(dir, 'index.ts'),
[
'/** Computes the running balance, marker EXPORTEDDOC. */',
'export function computeBalance(userId: number): number {',
' return userId;',
'}',
'',
].join('\n'),
);
return dir;
}
function createSwiftRepo(): string {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'doc-desc-swift-e2e-'));
fs.writeFileSync(
path.join(dir, 'Widget.swift'),
[
'class Widget {',
' /**',
' Renders the widget, marker SWIFTDOC.',
' Example:',
' #if os(iOS)',
' useUIKit()',
' #endif',
' */',
' func render() {}',
'}',
'',
].join('\n'),
);
return dir;
}
describe('doc-comment description end-to-end (issue #2270)', () => {
it('surfaces an exported function JSDoc as its node description through the pipeline', async () => {
const result: PipelineResult = await runPipelineFromRepo(createTsRepo(), () => {}, {
skipGraphPhases: true,
workerPoolSize: 2,
});
const descriptions = new Map<string, unknown>();
result.graph.forEachNode((node) => {
descriptions.set(`${node.label}:${node.properties.name}`, node.properties.description);
});
expect(result.usedWorkerPool).toBe(true);
expect(descriptions.get('Function:computeBalance')).toContain('EXPORTEDDOC');
});
// Swift preprocessing blanks nested conditional directives before parsing;
// doing that inside a doc comment would delete lines from `description` (#2771).
it.skipIf(!isLanguageAvailable(SupportedLanguages.Swift))(
'keeps directive lines inside a Swift doc comment in the node description',
async () => {
const result: PipelineResult = await runPipelineFromRepo(createSwiftRepo(), () => {}, {
skipGraphPhases: true,
workerPoolSize: 2,
});
const descriptions = new Map<string, unknown>();
result.graph.forEachNode((node) => {
descriptions.set(`${node.label}:${node.properties.name}`, node.properties.description);
});
expect(descriptions.get('Function:render')).toBe(
'Renders the widget, marker SWIFTDOC. Example: #if os(iOS) useUIKit() #endif',
);
},
);
});