diff --git a/frontend/package.json b/frontend/package.json index 1378c94..e62840a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,33 +1,35 @@ -{ - "name": "frontend", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@types/qrcode": "^1.5.6", - "highlight.js": "^11.11.1", - "html2canvas": "^1.4.1", - "jspdf": "^4.2.1", - "katex": "^0.17.0", - "mermaid": "^11.16.0", - "qrcode": "^1.5.4", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-router-dom": "^6.30.3" - }, - "devDependencies": { - "@types/react": "^18.3.29", - "@types/react-dom": "^18.3.7", - "@vitejs/plugin-react": "^4.7.0", - "typescript": "^5.9.3", - "vite": "^5.4.21" - } -} +{ + "name": "frontend", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "test": "vitest run" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@types/qrcode": "^1.5.6", + "highlight.js": "^11.11.1", + "html2canvas": "^1.4.1", + "jspdf": "^4.2.1", + "katex": "^0.17.0", + "mermaid": "^11.16.0", + "qrcode": "^1.5.4", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.30.3" + }, + "devDependencies": { + "@types/react": "^18.3.29", + "@types/react-dom": "^18.3.7", + "@vitejs/plugin-react": "^4.7.0", + "typescript": "^5.9.3", + "vite": "^5.4.21", + "vitest": "^4.1.10" + } +} diff --git a/frontend/src/utils/datetime.test.ts b/frontend/src/utils/datetime.test.ts new file mode 100644 index 0000000..05db8d3 --- /dev/null +++ b/frontend/src/utils/datetime.test.ts @@ -0,0 +1,29 @@ +import { describe, it, expect } from 'vitest'; +import { formatBjTime } from './datetime'; + +// 北京时间渲染曾是反复出现的问题(微信Bot时间错乱、Token驾驶舱时间列不正确等)。 +// 该测试固化「后端按北京时间存储、前端显式按 Asia/Shanghai 渲染」的契约。 +describe('formatBjTime', () => { + it('空输入返回占位符 -', () => { + expect(formatBjTime(undefined)).toBe('-'); + expect(formatBjTime(null)).toBe('-'); + expect(formatBjTime('')).toBe('-'); + }); + + it('无时区标记的时间戳按 Asia/Shanghai (+08:00) 渲染', () => { + // 2026-07-18T12:00:00 视为北京时间,渲染应含 12:00:00 + const out = formatBjTime('2026-07-18T12:00:00'); + expect(out).toContain('2026'); + expect(out).toContain('12:00:00'); + }); + + it('UTC(Z) 时间戳正确转换为北京时间 (+8)', () => { + // 2026-07-18T04:00:00Z = 北京时间 12:00:00 + const out = formatBjTime('2026-07-18T04:00:00Z'); + expect(out).toContain('12:00:00'); + }); + + it('非法日期原样返回', () => { + expect(formatBjTime('not-a-date')).toBe('not-a-date'); + }); +}); diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 6e583cc..d1d4947 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,4 +1,5 @@ -import { defineConfig } from 'vite'; +/// +import { defineConfig } from 'vitest/config'; import react from '@vitejs/plugin-react'; import path from 'path'; @@ -17,8 +18,6 @@ export default defineConfig({ chunkSizeWarningLimit: 1200, rollupOptions: { output: { - // 仅将 react 核心库单独打包(长期缓存); - // 其余第三方库交给 Rollup 自动按需拆分,避免被强制合并成一个大 vendor 在首屏加载 manualChunks(id) { if (id.includes('node_modules')) { if ( @@ -37,4 +36,9 @@ export default defineConfig({ server: { port: 5173, }, + // Phase 0 测试基建:vitest 配置(纯函数测试用 node 环境,组件测试可改 jsdom) + test: { + environment: 'node', + include: ['src/**/*.test.ts'], + }, });