import assert from 'node:assert/strict' import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, it } from 'node:test' import { DEFAULT_CONFIG } from '../config.ts' import { openCodeIntelligenceDb } from '../db/connection.ts' import { getEntityStats, listEntitiesForPath } from '../db/repositories/entitiesRepo.ts' import { getIndexingState } from '../db/repositories/indexingStateRepo.ts' import { extractEntitiesForFile } from '../indexing/entityExtractor.ts' import { runFullRepoIndex, runIncrementalIndex } from '../indexing/indexScheduler.ts' import type { CodeIntelligenceLogger } from '../logger.ts' import type { RepoIdentity } from '../repo/identifyRepo.ts' const silentLogger = { debug() {}, info() {}, warn() {}, error() {} } as unknown as CodeIntelligenceLogger describe('entity extraction', () => { it('extracts TS/JS declarations, React components, hooks, tests, and import metadata', () => { const entities = extractEntitiesForFile({ repoKey: 'repo', fileId: 1, path: 'src/App.tsx', packageKey: 'root', language: 'typescriptreact', content: [ "import React, { useMemo } from 'react'", "import type { User } from './types'", 'export interface Props { user: User }', 'export type Mode = "a" | "b"', 'export function useThing() { return useMemo(() => 1, []) }', 'export const AppScreen = (props: Props) => {', ' return ', '}', 'const valueSchema = {}', "describe('app screen', () => {", " test('renders', () => {})", '})', ].join('\n'), }) assert(entities.some((entity) => entity.name === 'src/App.tsx' && entity.kind === 'module' && JSON.stringify(entity.metadata).includes('react'))) assert(entities.some((entity) => entity.name === 'Props' && entity.kind === 'interface' && entity.exported)) assert(entities.some((entity) => entity.name === 'Mode' && entity.kind === 'type')) assert(entities.some((entity) => entity.name === 'useThing' && entity.kind === 'hook')) assert(entities.some((entity) => entity.name === 'AppScreen' && entity.kind === 'screen')) assert(entities.some((entity) => entity.name === 'valueSchema' && entity.kind === 'schema')) assert(entities.some((entity) => entity.name === 'app screen' && entity.kind === 'test_suite')) }) it('extracts JavaScript separately, including CommonJS imports', () => { const entities = extractEntitiesForFile({ repoKey: 'repo', fileId: 1, path: 'src/widget.jsx', language: 'javascriptreact', content: [ "const React = require('react')", "import Button from './Button'", 'export function Widget() {', ' return