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

+104
View File
@@ -0,0 +1,104 @@
import { strict as assert } from 'node:assert'
import { mkdtemp, mkdir, symlink, writeFile, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { test } from 'node:test'
import { DEFAULT_EXTENSIONS, extensionOf, globToRegExp, listCodeFiles, matchesAny } from '../lib/walk.js'
test('globToRegExp anchors and handles star and double-star', () => {
assert.equal(globToRegExp('src/*.ts').test('src/a.ts'), true)
assert.equal(globToRegExp('src/*.ts').test('src/nested/a.ts'), false)
assert.equal(globToRegExp('**/*.ts').test('a/b/c.ts'), true)
assert.equal(globToRegExp('**/*.ts').test('c.ts'), true)
assert.equal(globToRegExp('src/**').test('src/a/b/c.ts'), true)
assert.equal(globToRegExp('dist/').test('dist/a/b.js'), true)
assert.equal(globToRegExp('src/a?.ts').test('src/ab.ts'), true)
assert.equal(globToRegExp('src/a?.ts').test('src/abc.ts'), false)
// Dots must be literal, not wildcards.
assert.equal(globToRegExp('a.ts').test('axts'), false)
})
test('matchesAny ignores empty patterns', () => {
assert.equal(matchesAny('a/b.ts', ['']), false)
assert.equal(matchesAny('a/b.ts', ['', 'a/*.ts']), true)
})
test('extensionOf lowercases and rejects dotfiles', () => {
assert.equal(extensionOf('a/B.TS'), 'ts')
assert.equal(extensionOf('.gitignore'), '')
assert.equal(extensionOf('Makefile'), '')
})
test('listCodeFiles returns a deterministic sorted list of code files only', async () => {
const root = await mkdtemp(join(tmpdir(), 'recall-walk-'))
try {
await mkdir(join(root, 'src', 'nested'), { recursive: true })
await mkdir(join(root, 'node_modules', 'dep'), { recursive: true })
await writeFile(join(root, 'src', 'b.ts'), 'export const b = 1\n')
await writeFile(join(root, 'src', 'a.ts'), 'export const a = 1\n')
await writeFile(join(root, 'src', 'nested', 'c.py'), 'c = 1\n')
await writeFile(join(root, 'README.md'), '# not code\n')
await writeFile(join(root, 'node_modules', 'dep', 'index.js'), 'module.exports = 1\n')
const { files } = await listCodeFiles(root)
assert.deepEqual(
files.map((file) => file.path),
['src/a.ts', 'src/b.ts', 'src/nested/c.py'],
)
} finally {
await rm(root, { recursive: true, force: true })
}
})
test('listCodeFiles honours an extension filter and an exclude glob', async () => {
const root = await mkdtemp(join(tmpdir(), 'recall-walk-'))
try {
await mkdir(join(root, 'src', 'generated'), { recursive: true })
await writeFile(join(root, 'src', 'a.ts'), 'a\n')
await writeFile(join(root, 'src', 'generated', 'b.ts'), 'b\n')
await writeFile(join(root, 'src', 'c.py'), 'c\n')
const onlyTs = await listCodeFiles(root, { extensions: ['ts'] })
assert.deepEqual(onlyTs.files.map((file) => file.path), ['src/a.ts', 'src/generated/b.ts'])
const excluded = await listCodeFiles(root, { exclude: ['src/generated/'] })
assert.deepEqual(excluded.files.map((file) => file.path), ['src/a.ts', 'src/c.py'])
} finally {
await rm(root, { recursive: true, force: true })
}
})
test('listCodeFiles reports truncation instead of silently dropping files', async () => {
const root = await mkdtemp(join(tmpdir(), 'recall-walk-'))
try {
for (let at = 0; at < 5; at += 1) await writeFile(join(root, `f${at}.ts`), `${at}\n`)
const { files, truncated } = await listCodeFiles(root, { maxFiles: 2 })
assert.equal(files.length, 2)
assert.equal(truncated, true)
} finally {
await rm(root, { recursive: true, force: true })
}
})
test('listCodeFiles does not follow symlinks', async () => {
const root = await mkdtemp(join(tmpdir(), 'recall-walk-'))
const outside = await mkdtemp(join(tmpdir(), 'recall-outside-'))
try {
await writeFile(join(outside, 'secret.ts'), 'export const secret = 1\n')
await writeFile(join(root, 'real.ts'), 'export const real = 1\n')
await symlink(outside, join(root, 'linked'), 'dir')
const { files } = await listCodeFiles(root)
assert.deepEqual(files.map((file) => file.path), ['real.ts'])
} finally {
await rm(root, { recursive: true, force: true })
await rm(outside, { recursive: true, force: true })
}
})
test('the default extension set is code, not prose', () => {
assert.ok(DEFAULT_EXTENSIONS.includes('ts'))
assert.ok(DEFAULT_EXTENSIONS.includes('py'))
assert.ok(!DEFAULT_EXTENSIONS.includes('md'))
})