import { describe, expect, it } from 'vitest'; import i18n, { enKeys, setLocale, t, zhKeys } from '../src/i18n'; import zh from '../src/i18n/zh'; import en from '../src/i18n/en'; describe('i18n key 完整性', () => { it('zh 与 en 的 key 集合完全一致', () => { const missingInEn = [...zhKeys].filter(k => !enKeys.has(k)); const missingInZh = [...enKeys].filter(k => !zhKeys.has(k)); expect(missingInEn).toEqual([]); expect(missingInZh).toEqual([]); }); it('关键 key 存在', () => { expect(zhKeys.has('app.name')).toBe(true); expect(zhKeys.has('tab.home')).toBe(true); expect(zhKeys.has('home.title')).toBe(true); expect(zhKeys.has('settings.themeMode')).toBe(true); expect(zhKeys.has('errors.ledgerNotLoaded')).toBe(true); }); }); describe('i18n 翻译', () => { it('默认 locale 为 zh', () => { setLocale('zh'); expect(i18n.locale).toBe('zh'); expect(t('app.name')).toBe('Bean Mobile'); expect(t('tab.home')).toBe('首页'); }); it('切换到 en 后返回英文', () => { setLocale('en'); expect(t('tab.home')).toBe('Home'); expect(t('settings.themeLight')).toBe('Light'); setLocale('zh'); // 还原 }); it('占位符替换(zh)', () => { setLocale('zh'); expect(t('home.accounts', { count: 4, total: 10 })).toBe('4 个已开户账户 · 10 条桌面交易'); }); it('占位符替换(en)', () => { setLocale('en'); expect(t('home.accounts', { count: 4, total: 10 })).toBe('4 open accounts · 10 desktop transactions'); setLocale('zh'); }); it('未知 key 返回 missing 标记(fallback)', () => { setLocale('zh'); expect(t('nonexistent.key')).toContain('missing'); expect(t('nonexistent.key')).toContain('nonexistent.key'); }); }); describe('i18n 结构一致性', () => { it('zh 与 en 顶层模块一致', () => { const zhModules = Object.keys(zh).sort(); const enModules = Object.keys(en).sort(); expect(zhModules).toEqual(enModules); }); });