allinssl/frontend/plugin/vite-plugin-i18n/__tests__/log.test.js

134 lines
3.8 KiB
JavaScript

import { jest } from '@jest/globals'
import { promises as fs } from 'fs'
import path from 'path'
import { LogManager } from '../src/logManagement/index.js'
jest.mock('fs', () => ({
promises: {
mkdir: jest.fn(),
appendFile: jest.fn(),
readFile: jest.fn(),
readdir: jest.fn(),
stat: jest.fn(),
unlink: jest.fn(),
},
}))
describe('LogManager', () => {
const options = {
logPath: './test-logs',
errorLogFile: 'error.log',
infoLogFile: 'info.log',
}
let logManager
beforeEach(() => {
logManager = new LogManager(options)
jest.clearAllMocks()
})
describe('init', () => {
it('应该创建日志目录', async () => {
await logManager.init()
expect(fs.mkdir).toHaveBeenCalledWith(options.logPath, { recursive: true })
})
it('处理创建目录失败的情况', async () => {
const consoleError = jest.spyOn(console, 'error').mockImplementation()
fs.mkdir.mockRejectedValueOnce(new Error('创建目录失败'))
await logManager.init()
expect(consoleError).toHaveBeenCalled()
consoleError.mockRestore()
})
})
describe('logError', () => {
it('应该写入错误日志', async () => {
const error = new Error('测试错误')
await logManager.logError(error)
expect(fs.appendFile).toHaveBeenCalledWith(
expect.stringContaining('error.log'),
expect.stringContaining('测试错误'),
)
})
it('处理写入错误日志失败的情况', async () => {
const consoleError = jest.spyOn(console, 'error').mockImplementation()
fs.appendFile.mockRejectedValueOnce(new Error('写入失败'))
await logManager.logError(new Error('测试错误'))
expect(consoleError).toHaveBeenCalled()
consoleError.mockRestore()
})
})
describe('logInfo', () => {
it('应该写入信息日志', async () => {
const message = '测试信息'
await logManager.logInfo(message)
expect(fs.appendFile).toHaveBeenCalledWith(expect.stringContaining('info.log'), expect.stringContaining(message))
})
it('处理写入信息日志失败的情况', async () => {
const consoleError = jest.spyOn(console, 'error').mockImplementation()
fs.appendFile.mockRejectedValueOnce(new Error('写入失败'))
await logManager.logInfo('测试信息')
expect(consoleError).toHaveBeenCalled()
consoleError.mockRestore()
})
})
describe('cleanLogs', () => {
it('应该删除过期的日志文件', async () => {
const now = Date.now()
const oldDate = now - 7 * 24 * 60 * 60 * 1000 - 1000 // 7天+1秒前
fs.readdir.mockResolvedValueOnce(['old.log', 'new.log'])
fs.stat.mockImplementation((path) => {
return Promise.resolve({
mtimeMs: path.includes('old') ? oldDate : now,
})
})
await logManager.cleanLogs(7)
expect(fs.unlink).toHaveBeenCalledWith(expect.stringContaining('old.log'))
expect(fs.unlink).not.toHaveBeenCalledWith(expect.stringContaining('new.log'))
})
it('处理清理日志失败的情况', async () => {
const consoleError = jest.spyOn(console, 'error').mockImplementation()
fs.readdir.mockRejectedValueOnce(new Error('读取目录失败'))
await logManager.cleanLogs(7)
expect(consoleError).toHaveBeenCalled()
consoleError.mockRestore()
})
})
describe('getLogs', () => {
it('应该返回指定数量的日志行', async () => {
const logContent = '行1\n行2\n行3\n行4\n行5'
fs.readFile.mockResolvedValueOnce(logContent)
const lines = await logManager.getLogs('info', 3)
expect(lines).toHaveLength(3)
expect(lines[2]).toBe('行5')
})
it('处理读取日志失败的情况', async () => {
const consoleError = jest.spyOn(console, 'error').mockImplementation()
fs.readFile.mockRejectedValueOnce(new Error('读取文件失败'))
const lines = await logManager.getLogs('error', 5)
expect(lines).toHaveLength(0)
expect(consoleError).toHaveBeenCalled()
consoleError.mockRestore()
})
})
})