diff --git a/app/api/__tests__/projects.test.ts b/app/api/__tests__/projects.test.ts index b931c5f..5bfea8e 100644 --- a/app/api/__tests__/projects.test.ts +++ b/app/api/__tests__/projects.test.ts @@ -6,7 +6,7 @@ import { GET } from '../projects/route'; import { getProjects } from '@/lib/fs-utils'; jest.mock('@/lib/fs-utils'); -jest.mock('@/lib/utils', () => ({ +jest.mock('@/lib/project-utils', () => ({ getProjectDisplayName: jest.fn((name) => name === 'FT' ? '外放构建' : name), })); diff --git a/app/api/projects/route.ts b/app/api/projects/route.ts index affdcd4..71fa03f 100644 --- a/app/api/projects/route.ts +++ b/app/api/projects/route.ts @@ -1,7 +1,7 @@ // app/api/projects/route.ts import { NextResponse } from 'next/server'; import { getProjects } from '@/lib/fs-utils'; -import { getProjectDisplayName } from '@/lib/utils'; +import { getProjectDisplayName } from '@/lib/project-utils'; export async function GET() { try { diff --git a/lib/__tests__/project-utils.test.ts b/lib/__tests__/project-utils.test.ts new file mode 100644 index 0000000..c357c04 --- /dev/null +++ b/lib/__tests__/project-utils.test.ts @@ -0,0 +1,44 @@ +import { getProjectDisplayName } from '../project-utils'; + +// Mock fs module +const fs = require('fs'); +const path = require('path'); +jest.mock('fs'); +jest.mock('path'); + +describe('getProjectDisplayName', () => { + const originalAliases = { + 'FT': '外放构建', + 'FT_DEV': '开发构建', + }; + + beforeEach(() => { + // Mock the aliases file + path.join.mockReturnValue('/mock/lib/project-aliases.json'); + fs.readFileSync.mockReturnValue(JSON.stringify(originalAliases)); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should return display name for aliased project', () => { + expect(getProjectDisplayName('FT')).toBe('外放构建'); + }); + + it('should return directory name when no alias exists', () => { + expect(getProjectDisplayName('UNKNOWN')).toBe('UNKNOWN'); + }); + + it('should return directory name when aliases file is empty', () => { + fs.readFileSync.mockReturnValue('{}'); + expect(getProjectDisplayName('FT')).toBe('FT'); + }); + + it('should return directory name when aliases file cannot be read', () => { + fs.readFileSync.mockImplementation(() => { + throw new Error('File not found'); + }); + expect(getProjectDisplayName('FT')).toBe('FT'); + }); +}); diff --git a/lib/__tests__/utils.test.ts b/lib/__tests__/utils.test.ts index 218985d..800ebc9 100644 --- a/lib/__tests__/utils.test.ts +++ b/lib/__tests__/utils.test.ts @@ -1,11 +1,4 @@ -import { formatVersion, formatFileSize, formatDateTime, getProjectDisplayName } from '../utils'; - -// Mock fs module -const fs = require('fs'); -jest.mock('fs', () => ({ - ...jest.requireActual('fs'), - readFileSync: jest.fn(), -})); +import { formatVersion, formatFileSize, formatDateTime } from '../utils'; describe('formatVersion', () => { test('应该将下划线替换为点号', () => { @@ -70,39 +63,3 @@ describe('formatDateTime', () => { expect(formatDateTime(date)).toBe('2024-01-05 09:05'); }); }); - -describe('getProjectDisplayName', () => { - const originalAliases = { - 'FT': '外放构建', - 'FT_DEV': '开发构建', - }; - - beforeEach(() => { - // Mock the aliases file - fs.readFileSync.mockReturnValue(JSON.stringify(originalAliases)); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it('should return display name for aliased project', () => { - expect(getProjectDisplayName('FT')).toBe('外放构建'); - }); - - it('should return directory name when no alias exists', () => { - expect(getProjectDisplayName('UNKNOWN')).toBe('UNKNOWN'); - }); - - it('should return directory name when aliases file is empty', () => { - fs.readFileSync.mockReturnValue('{}'); - expect(getProjectDisplayName('FT')).toBe('FT'); - }); - - it('should return directory name when aliases file cannot be read', () => { - fs.readFileSync.mockImplementation(() => { - throw new Error('File not found'); - }); - expect(getProjectDisplayName('FT')).toBe('FT'); - }); -}); diff --git a/lib/project-utils.ts b/lib/project-utils.ts new file mode 100644 index 0000000..c8a36db --- /dev/null +++ b/lib/project-utils.ts @@ -0,0 +1,19 @@ +// lib/project-utils.ts +// Server-only utility functions +import * as fs from 'fs'; +import * as path from 'path'; + +/** + * 获取项目显示名称(从别名配置) + */ +export function getProjectDisplayName(projectName: string): string { + try { + const aliasesPath = path.join(process.cwd(), 'lib', 'project-aliases.json'); + const aliasesContent = fs.readFileSync(aliasesPath, 'utf-8'); + const aliases = JSON.parse(aliasesContent); + return aliases[projectName] || projectName; + } catch { + // If file doesn't exist or is invalid, return original name + return projectName; + } +} diff --git a/lib/utils.ts b/lib/utils.ts index 295e82d..88b3e4f 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,7 +1,5 @@ // lib/utils.ts // Client-safe utility functions -import * as fs from 'fs'; -import * as path from 'path'; /** * 格式化版本号显示 (0_42 -> 0.42) @@ -31,18 +29,3 @@ export function formatDateTime(date: Date): string { const minutes = String(date.getMinutes()).padStart(2, '0'); return `${year}-${month}-${day} ${hours}:${minutes}`; } - -/** - * 获取项目显示名称(从别名配置) - */ -export function getProjectDisplayName(projectName: string): string { - try { - const aliasesPath = path.join(process.cwd(), 'lib', 'project-aliases.json'); - const aliasesContent = fs.readFileSync(aliasesPath, 'utf-8'); - const aliases = JSON.parse(aliasesContent); - return aliases[projectName] || projectName; - } catch { - // If file doesn't exist or is invalid, return original name - return projectName; - } -}