本地 RAG 知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

100 lines
2.7 KiB

/**
* i18n.ts 国际化模块单元测试
*/
import { describe, it, expect, beforeEach } from 'vitest';
import { t, setLocale, getLocale } from '../src/i18n';
describe('setLocale / getLocale', () => {
beforeEach(() => {
setLocale('zh-CN');
});
it('默认语言为 zh-CN', () => {
expect(getLocale()).toBe('zh-CN');
});
it('切换为英文', () => {
setLocale('en');
expect(getLocale()).toBe('en');
});
it('匹配语言前缀(zh → zh-CN)', () => {
setLocale('zh');
expect(getLocale()).toBe('zh-CN');
});
it('未知语言保持默认 zh-CN', () => {
setLocale('fr');
expect(getLocale()).toBe('zh-CN');
});
});
describe('t()', () => {
beforeEach(() => {
setLocale('zh-CN');
});
it('返回中文翻译', () => {
expect(t('send')).toBe('发送');
expect(t('close')).toBe('关闭');
});
it('切换英文后返回英文翻译', () => {
setLocale('en');
expect(t('send')).toBe('Send');
expect(t('close')).toBe('Close');
});
it('未知 key 返回 key 本身', () => {
expect(t('nonexistent_key')).toBe('nonexistent_key');
});
it('支持插值参数替换', () => {
setLocale('zh-CN');
expect(t('source_count', { n: 3 })).toBe('3 条参考来源');
});
it('英文插值参数替换', () => {
setLocale('en');
expect(t('source_count', { n: 5 })).toBe('5 source(s)');
});
it('中英文字典 key 数量一致', () => {
// 验证中英文字典完整性:所有中文 key 在英文中都有对应
setLocale('zh-CN');
const zhKeys = Object.keys(getAllKeys('zh-CN'));
setLocale('en');
const enKeys = Object.keys(getAllKeys('en'));
// 每个中文 key 在英文字典中也应存在
for (const key of zhKeys) {
setLocale('en');
const translated = t(key);
expect(translated).not.toBe(key); // 不应回退到 key 本身
}
});
});
/** 辅助函数:获取指定语言的所有 key(通过遍历测试已知 key) */
function getAllKeys(_locale: string): Record<string, string> {
const knownKeys = [
'title', 'minimize', 'close', 'status_online',
'welcome_title', 'welcome_desc',
'placeholder', 'send', 'stop', 'new_message',
'copy', 'copied', 'retry',
'loading', 'stream_interrupted',
'category_all', 'source_count',
'clear', 'clear_confirm',
'history_title', 'history_empty', 'history_search',
'feedback_up', 'feedback_down',
'teaser_text', 'new_msg_announce',
'error_network', 'error_timeout', 'error_send',
'history_group_today', 'history_group_yesterday',
'history_group_week', 'history_group_earlier',
];
const result: Record<string, string> = {};
for (const key of knownKeys) {
result[key] = t(key);
}
return result;
}