This commit is contained in:
NotExpectedYet committed 2026-09-26 05:35:29 +01:00
commit 0964819cdc
34 files changed
+7912

No files matched your search

+150
View File
@@ -0,0 +1,150 @@
import { strict as assert } from 'node:assert'
import { test } from 'node:test'
import {
chunkFile,
embedText,
isLikelyMinified,
languageOf,
symbolLabel,
symbolOf,
} from '../lib/chunk.js'
const TS = `import { readFile } from 'node:fs/promises'
const CACHE = new Map()
export function loadConfig(path) {
if (CACHE.has(path)) return CACHE.get(path)
const value = { path, loaded: true }
CACHE.set(path, value)
return value
}
export function clearCache() {
CACHE.clear()
}
export class Store {
constructor() {
this.rows = []
}
add(row) {
this.rows.push(row)
}
}
`
/** A module long enough that its declarations cannot all merge into one chunk. */
function bigModule(count = 6, bodyLines = 14) {
const parts = []
for (let at = 0; at < count; at += 1) {
const body = Array.from({ length: bodyLines }, (_, line) => ` const step_${at}_${line} = compute(${line})`).join('\n')
parts.push(`export function handler_${at}(input) {\n${body}\n return input\n}`)
}
return `${parts.join('\n\n')}\n`
}
test('languageOf maps known extensions and ignores unknown ones', () => {
assert.equal(languageOf('a/b.ts'), 'javascript')
assert.equal(languageOf('a/b.PY'), 'python')
assert.equal(languageOf('a/b.rs'), 'rust')
assert.equal(languageOf('a/b.unknownext'), undefined)
assert.equal(languageOf('Makefile'), undefined)
})
test('symbolOf reads a declaration name', () => {
assert.equal(symbolOf('export function loadConfig(path) {'), 'loadConfig')
assert.equal(symbolOf('export class Store {'), 'Store')
assert.equal(symbolOf('def compute_total(items):'), 'compute_total')
assert.equal(symbolOf('// just a comment'), undefined)
})
test('symbolLabel lists merged declarations and caps a long list', () => {
assert.equal(symbolLabel([]), undefined)
assert.equal(symbolLabel(['a']), 'a')
assert.equal(symbolLabel(['a', 'b']), 'a, b')
assert.equal(symbolLabel(['a', 'a', 'b']), 'a, b')
assert.equal(symbolLabel(['a', 'b', 'c', 'd', 'e', 'f']), 'a, b, c, d +2')
})
test('a small file merges into one chunk labelled with every declaration it holds', () => {
const { chunks } = chunkFile({ path: 'src/config.ts', content: TS })
assert.equal(chunks.length, 1, 'a 25-line file belongs in a single chunk')
// The label must describe the whole chunk, not just its first declaration:
// for a small file this label is the module's only description in the index.
assert.equal(chunks[0].symbol, 'CACHE, loadConfig, clearCache, Store')
assert.equal(chunks[0].startLine, 1)
})
test('a larger file splits at declarations, and each chunk is a real source slice', () => {
const content = bigModule()
const { chunks } = chunkFile({ path: 'src/handlers.ts', content })
assert.ok(chunks.length >= 3, `expected several chunks, got ${chunks.length}`)
const lines = content.split('\n')
for (const chunk of chunks) {
assert.equal(chunk.text, lines.slice(chunk.startLine - 1, chunk.endLine).join('\n'))
}
assert.equal(chunks[0].startLine, 1)
assert.match(chunks[0].symbol, /handler_0/)
})
test('chunkFile merges adjacent small declarations instead of emitting fragments', () => {
const source = ['export function a() { return 1 }', '', 'export function b() { return 2 }', '', 'export function c() { return 3 }', ''].join('\n')
const { chunks } = chunkFile({ path: 'x.ts', content: source, chunkLines: 48 })
assert.equal(chunks.length, 1, 'three one-line functions should merge into one chunk')
assert.equal(chunks[0].symbol, 'a, b, c')
})
test('chunkFile splits an oversized declaration with overlap', () => {
const body = Array.from({ length: 300 }, (_, at) => ` const value_${at} = compute(${at})`).join('\n')
const source = `export function huge() {\n${body}\n}\n`
const { chunks } = chunkFile({ path: 'x.ts', content: source, maxChunkLines: 80, overlapLines: 8 })
assert.ok(chunks.length > 1, 'a 300-line function must be split')
for (const chunk of chunks) {
assert.ok(chunk.endLine - chunk.startLine + 1 <= 80, `chunk was ${chunk.endLine - chunk.startLine + 1} lines`)
}
// Overlap means consecutive chunks share lines, so no boundary is lost.
for (let at = 1; at < chunks.length; at += 1) {
assert.ok(chunks[at].startLine <= chunks[at - 1].endLine, 'consecutive chunks should overlap')
}
// Only the piece holding the signature is labelled with the declaration.
assert.equal(chunks[0].symbol, 'huge')
assert.equal(chunks[1].symbol, undefined)
})
test('chunkFile falls back to windows when the language has no anchor set', () => {
const source = Array.from({ length: 200 }, (_, at) => `line ${at} of an unknown dialect`).join('\n')
const { chunks } = chunkFile({ path: 'thing.weird', content: source, maxChunkLines: 80, overlapLines: 8 })
assert.ok(chunks.length > 1)
assert.equal(chunks[0].startLine, 1)
assert.equal(chunks[0].symbol, undefined)
})
test('chunkFile refuses generated files rather than indexing noise', () => {
const minified = `var a=${'x'.repeat(50_000)};`
assert.equal(isLikelyMinified(minified), true)
const result = chunkFile({ path: 'bundle.js', content: minified })
assert.deepEqual(result.chunks, [])
assert.equal(result.skipped, 'generated-or-minified')
})
test('chunkFile reports an empty file as empty', () => {
const result = chunkFile({ path: 'a.ts', content: ' \n\n' })
assert.deepEqual(result.chunks, [])
assert.equal(result.skipped, 'empty')
})
test('chunkFile caps chunks per file', () => {
const source = Array.from({ length: 400 }, (_, at) => `export function fn_${at}() { return ${at} }`).join('\n')
const { chunks, skipped } = chunkFile({ path: 'many.ts', content: source, chunkLines: 2, maxChunkLines: 2, maxChunks: 10 })
assert.equal(chunks.length, 10)
assert.equal(skipped, 'chunk-cap-reached')
})
test('embedText carries the path, so a question about a name can find it', () => {
const text = embedText('src/auth/session.ts', { symbol: 'issueSession', text: 'export function issueSession() {}' })
assert.match(text, /src\/auth\/session\.ts :: issueSession/)
assert.match(text, /export function issueSession/)
})