feat(web): заготовка веб-клиента на Vite + React 19 + TypeScript strict
- стек по §5.2: React 19, React Router, TanStack Query, Zustand, Tailwind CSS 4, i18next (ru/en), Vitest + Testing Library - дизайн-токены §3 docs/client-web.md (тёмная тема по умолчанию, светлая, accent) - типизированный API-клиент §8.1: единый формат ошибок, ApiError с кодом - App: экран состояния фундамента с readz/meta, локализация ошибок по code - тесты: клиент API, форматирование, рендер App (успех/ошибка кода/сеть) - eslint + prettier + tsc strict; initial JS 97.6 KB gzip
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { errorCode, formatBytes } from '@/lib/format';
|
||||
import { ApiError } from '@/api/client';
|
||||
|
||||
describe('formatBytes', () => {
|
||||
it('renders human readable sizes', () => {
|
||||
expect(formatBytes(512)).toBe('512 B');
|
||||
expect(formatBytes(1024)).toBe('1 KB');
|
||||
expect(formatBytes(26214400)).toBe('25 MB');
|
||||
expect(formatBytes(1073741824)).toBe('1 GB');
|
||||
});
|
||||
|
||||
it('handles invalid input', () => {
|
||||
expect(formatBytes(-1)).toBe('—');
|
||||
expect(formatBytes(Number.NaN)).toBe('—');
|
||||
});
|
||||
});
|
||||
|
||||
describe('errorCode', () => {
|
||||
it('extracts the server error code', () => {
|
||||
expect(errorCode(new ApiError(403, 'perm.denied', 'nope'))).toBe('perm.denied');
|
||||
});
|
||||
|
||||
it('maps unknown failures to a network code', () => {
|
||||
expect(errorCode(new Error('socket hang up'))).toBe('network.unreachable');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user