/** * 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, workerThresholdsForTest: { minFiles: 1, minBytes: 1 }, workerPoolSize: 2, }); const descriptions = new Map(); 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, workerThresholdsForTest: { minFiles: 1, minBytes: 1 }, workerPoolSize: 2, }); const descriptions = new Map(); 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', ); }, ); });