2026-07-15 21:06:36 +08:00

66 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { existsSync, mkdtempSync, readdirSync, realpathSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { basename, dirname, join, resolve, sep } from 'node:path'
import { spawnSync } from 'node:child_process'
import { fileURLToPath } from 'node:url'
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const testPrefix = 'yyd-notification-center-test-'
const testRoot = mkdtempSync(join(tmpdir(), testPrefix))
const databasePath = join(testRoot, 'notifications.db')
const databaseUrl = `file:${databasePath}`
const childEnv = { ...process.env, DATABASE_URL: databaseUrl }
// Prisma 5.22 的 Windows schema-engine 在部分主机未初始化 Rust 日志时会无细节提前退出。
// 只在 Windows 测试子进程中启用;Linux/Docker 不受影响,也不会记录数据库内容或密钥。
if (process.platform === 'win32' && !childEnv.RUST_LOG) childEnv.RUST_LOG = 'trace'
const runNode = (args) => {
const result = spawnSync(process.execPath, args, {
cwd: repoRoot,
env: childEnv,
stdio: 'inherit',
})
if (result.error) throw result.error
return result.status ?? 1
}
const removeTestRoot = () => {
const resolvedTemp = realpathSync(tmpdir())
const resolvedTestRoot = realpathSync(testRoot)
const isTempChild = resolvedTestRoot.startsWith(`${resolvedTemp}${sep}`)
if (!isTempChild || !basename(resolvedTestRoot).startsWith(testPrefix)) {
throw new Error(`拒绝清理非测试临时目录: ${resolvedTestRoot}`)
}
rmSync(resolvedTestRoot, { recursive: true, force: true })
if (existsSync(resolvedTestRoot)) throw new Error('测试临时目录清理失败')
}
let exitCode = 0
try {
const prismaCli = resolve(repoRoot, 'node_modules', 'prisma', 'build', 'index.js')
const schema = resolve(repoRoot, 'prisma', 'schema.prisma')
exitCode = runNode([prismaCli, 'migrate', 'deploy', '--schema', schema])
if (exitCode === 0) {
const tsxCli = resolve(repoRoot, 'node_modules', 'tsx', 'dist', 'cli.mjs')
const testsDirectory = resolve(repoRoot, 'src', '__tests__')
const testFiles = readdirSync(testsDirectory)
.filter((name) => name.endsWith('.test.ts'))
.sort()
.map((name) => resolve(testsDirectory, name))
if (testFiles.length === 0) throw new Error('未找到测试文件')
exitCode = runNode([tsxCli, '--test', '--test-concurrency=1', ...testFiles])
}
} catch (error) {
console.error('[test-runner]', error instanceof Error ? error.message : String(error))
exitCode = 1
} finally {
try {
removeTestRoot()
} catch (error) {
console.error('[test-runner-cleanup]', error instanceof Error ? error.message : String(error))
exitCode = 1
}
}
process.exitCode = exitCode