60 lines
2.5 KiB
TypeScript
60 lines
2.5 KiB
TypeScript
import { describe, expect, test } from 'vitest';
|
|
import { readFileSync } from 'fs';
|
|
import { resolve } from 'path';
|
|
|
|
import {
|
|
inferKokoroLanguageFromVoice,
|
|
normalizeUnicodeToken,
|
|
resolveTtsLanguage,
|
|
segmentSentences,
|
|
segmentWords,
|
|
toBaseLanguageCode,
|
|
} from '../../src/lib/shared/language';
|
|
|
|
describe('multilingual language utilities', () => {
|
|
test('keeps the multilingual document fixture readable as UTF-8', () => {
|
|
const fixture = readFileSync(resolve(process.cwd(), 'tests/files/multilingual-sample.txt'), 'utf8');
|
|
expect(fixture).toContain('これは二番目の文です。');
|
|
expect(fixture).toContain('这是第二句话。');
|
|
expect(fixture).toContain('هذه هي الجملة الثانية.');
|
|
});
|
|
|
|
test('infers Kokoro language from a single-language voice selection', () => {
|
|
expect(inferKokoroLanguageFromVoice('jf_alpha')).toBe('ja');
|
|
expect(inferKokoroLanguageFromVoice('zf_xiaobei(0.5)+zm_yunxi(0.5)')).toBe('zh-CN');
|
|
expect(inferKokoroLanguageFromVoice('ff_siwis+jf_alpha')).toBeNull();
|
|
});
|
|
|
|
test('prefers an explicit language and resolves regional tags for Whisper', () => {
|
|
expect(resolveTtsLanguage({ configuredLanguage: 'pt-BR', voice: 'jf_alpha' })).toBe('pt-BR');
|
|
expect(resolveTtsLanguage({ configuredLanguage: 'auto', voice: 'jf_alpha' })).toBe('ja');
|
|
expect(toBaseLanguageCode('zh-CN')).toBe('zh');
|
|
});
|
|
|
|
test('normalizes Unicode tokens without dropping non-Latin scripts', () => {
|
|
expect(normalizeUnicodeToken('École!')).toBe('école');
|
|
expect(normalizeUnicodeToken('日本語。')).toBe('日本語');
|
|
expect(normalizeUnicodeToken('العربية؟')).toBe('العربية');
|
|
expect(normalizeUnicodeToken('हिन्दी।')).toBe('हिन्दी');
|
|
});
|
|
|
|
test('segments CJK sentences and no-space language words', () => {
|
|
expect(segmentSentences('これは最初の文です。これは二番目の文です。', 'ja')).toEqual([
|
|
'これは最初の文です。',
|
|
'これは二番目の文です。',
|
|
]);
|
|
|
|
const chineseWords = segmentWords('这是第一句话。', 'zh').map((token) => token.text);
|
|
expect(chineseWords.length).toBeGreaterThan(1);
|
|
expect(chineseWords.join('')).toBe('这是第一句话');
|
|
});
|
|
|
|
test('preserves source offsets for Thai word segmentation', () => {
|
|
const text = 'นี่คือประโยคแรก';
|
|
const words = segmentWords(text, 'th');
|
|
expect(words.length).toBeGreaterThan(1);
|
|
for (const word of words) {
|
|
expect(text.slice(word.start, word.end)).toBe(word.text);
|
|
}
|
|
});
|
|
});
|