test: add i18n and highlight.js test suites (18 cases, 95 total)
This commit is contained in:
64
src/lib/__tests__/highlight.test.ts
Normal file
64
src/lib/__tests__/highlight.test.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import hljs, { rehypeHighlightLanguages, rehypeHighlightOptions } from '../highlight';
|
||||
|
||||
describe('highlight', () => {
|
||||
const expectedLanguages = [
|
||||
'bash', 'css', 'diff', 'dockerfile', 'go', 'ini',
|
||||
'javascript', 'json', 'markdown', 'python', 'rust',
|
||||
'shell', 'sql', 'typescript', 'xml', 'yaml',
|
||||
];
|
||||
|
||||
describe('hljs instance', () => {
|
||||
it('has all expected languages registered', () => {
|
||||
const registered = hljs.listLanguages();
|
||||
for (const lang of expectedLanguages) {
|
||||
expect(registered).toContain(lang);
|
||||
}
|
||||
});
|
||||
|
||||
it('resolves common aliases', () => {
|
||||
const aliases = ['sh', 'zsh', 'js', 'jsx', 'ts', 'tsx', 'py', 'html', 'yml', 'rs'];
|
||||
for (const alias of aliases) {
|
||||
const lang = hljs.getLanguage(alias);
|
||||
expect(lang, `alias "${alias}" should resolve`).toBeDefined();
|
||||
}
|
||||
});
|
||||
|
||||
it('highlights JavaScript code', () => {
|
||||
const result = hljs.highlight('const x = 42;', { language: 'javascript' });
|
||||
expect(result.value).toContain('hljs-');
|
||||
expect(result.language).toBe('javascript');
|
||||
});
|
||||
|
||||
it('highlights Python code', () => {
|
||||
const result = hljs.highlight('def hello():\n pass', { language: 'python' });
|
||||
expect(result.value).toContain('hljs-');
|
||||
});
|
||||
|
||||
it('auto-detects language', () => {
|
||||
const result = hljs.highlightAuto('{"key": "value"}');
|
||||
expect(result.language).toBe('json');
|
||||
});
|
||||
});
|
||||
|
||||
describe('rehypeHighlightLanguages', () => {
|
||||
it('exports all expected languages as functions', () => {
|
||||
for (const lang of expectedLanguages) {
|
||||
expect(typeof rehypeHighlightLanguages[lang]).toBe('function');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('rehypeHighlightOptions', () => {
|
||||
it('has languages and aliases', () => {
|
||||
expect(rehypeHighlightOptions.languages).toBeDefined();
|
||||
expect(rehypeHighlightOptions.aliases).toBeDefined();
|
||||
});
|
||||
|
||||
it('aliases map to valid language names', () => {
|
||||
for (const [lang] of Object.entries(rehypeHighlightOptions.aliases)) {
|
||||
expect(expectedLanguages).toContain(lang);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
90
src/lib/__tests__/i18n.test.ts
Normal file
90
src/lib/__tests__/i18n.test.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { describe, it, expect, afterEach } from 'vitest';
|
||||
import { t, getLocale, setLocale, supportedLocales, localeLabels } from '../i18n';
|
||||
|
||||
describe('i18n', () => {
|
||||
const originalLocale = getLocale();
|
||||
|
||||
afterEach(() => {
|
||||
setLocale(originalLocale);
|
||||
});
|
||||
|
||||
describe('supportedLocales', () => {
|
||||
it('includes en and fr', () => {
|
||||
expect(supportedLocales).toContain('en');
|
||||
expect(supportedLocales).toContain('fr');
|
||||
});
|
||||
|
||||
it('has labels for all supported locales', () => {
|
||||
for (const loc of supportedLocales) {
|
||||
expect(localeLabels[loc]).toBeDefined();
|
||||
expect(typeof localeLabels[loc]).toBe('string');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLocale / setLocale', () => {
|
||||
it('returns a supported locale', () => {
|
||||
expect(supportedLocales).toContain(getLocale());
|
||||
});
|
||||
|
||||
it('switches locale', () => {
|
||||
setLocale('fr');
|
||||
expect(getLocale()).toBe('fr');
|
||||
setLocale('en');
|
||||
expect(getLocale()).toBe('en');
|
||||
});
|
||||
});
|
||||
|
||||
describe('t()', () => {
|
||||
it('returns English strings when locale is en', () => {
|
||||
setLocale('en');
|
||||
expect(t('login.connect')).toBe('Connect');
|
||||
});
|
||||
|
||||
it('returns French strings when locale is fr', () => {
|
||||
setLocale('fr');
|
||||
expect(t('login.connect')).toBe('Connexion');
|
||||
});
|
||||
|
||||
it('returns the key itself for unknown keys', () => {
|
||||
setLocale('en');
|
||||
// Cast to bypass TS — simulates a missing key at runtime
|
||||
const result = t('nonexistent.key' as never);
|
||||
expect(result).toBe('nonexistent.key');
|
||||
});
|
||||
|
||||
it('all en keys have corresponding fr translations', () => {
|
||||
setLocale('en');
|
||||
const enResult = t('login.title');
|
||||
setLocale('fr');
|
||||
const frResult = t('login.title');
|
||||
// Both should return non-empty strings (not the key)
|
||||
expect(enResult.length).toBeGreaterThan(0);
|
||||
expect(frResult.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onLocaleChange', () => {
|
||||
it('notifies listeners on locale change', async () => {
|
||||
const { onLocaleChange } = await import('../i18n');
|
||||
let callCount = 0;
|
||||
const unsub = onLocaleChange(() => callCount++);
|
||||
|
||||
setLocale('fr');
|
||||
setLocale('en');
|
||||
|
||||
expect(callCount).toBe(2);
|
||||
unsub();
|
||||
});
|
||||
|
||||
it('unsubscribe stops notifications', async () => {
|
||||
const { onLocaleChange } = await import('../i18n');
|
||||
let callCount = 0;
|
||||
const unsub = onLocaleChange(() => callCount++);
|
||||
unsub();
|
||||
|
||||
setLocale('fr');
|
||||
expect(callCount).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user