Bonsai-Chat-WebGPU / src /app /components /ComposerActivity.test.tsx
Valeriy Selitskiy
Release v1.2.1 adaptive chat workspace
6c62075
Raw
History Blame Contribute Delete
2.37 kB
import { renderToStaticMarkup } from 'react-dom/server';
import { describe, expect, it } from 'vitest';
import type { ModelLoadProgress, ModelShardProgress } from '../../lib/contracts';
import { ComposerActivity, describeLoadProgress, overallLoadProgress } from './ComposerActivity';
function shard(index: number, state: ModelShardProgress['state']): ModelShardProgress {
return {
index,
path: `shard-${index + 1}.gguf`,
loadedBytes: state === 'queued' ? 0 : 100,
verifiedBytes: state === 'complete' || state === 'cached' ? 100 : 0,
totalBytes: 100,
state,
};
}
function progress(overrides: Partial<ModelLoadProgress> = {}): ModelLoadProgress {
return {
modelId: 'bonsai-27b',
modelLabel: 'Bonsai 27B',
stage: 'download',
stageProgress: 0.5,
downloadedBytes: 400,
totalBytes: 800,
residentBytes: 0,
nativeStage: null,
shards: [
shard(0, 'complete'),
shard(1, 'downloading'),
...Array.from({ length: 6 }, (_, index) => shard(index + 2, 'queued')),
],
...overrides,
};
}
describe('ComposerActivity', () => {
it('combines the load pipeline into one weighted overall progress value', () => {
expect(overallLoadProgress(progress())).toBeCloseTo(0.39625);
expect(overallLoadProgress(progress({ stage: 'cache', stageProgress: 0.2 }))).toBeCloseTo(0.39625);
expect(overallLoadProgress(progress({ stage: 'load', stageProgress: 0.5 }))).toBeCloseTo(0.95);
expect(overallLoadProgress(progress({ stage: 'ready' }))).toBe(1);
});
it('annotates the active shard and total ready shard count', () => {
expect(describeLoadProgress(progress())).toEqual({
label: 'Downloading shard 2 of 8',
detail: '1 of 8 shards ready · 400 B / 800 B',
});
});
it('renders exactly one progressbar during load and disappears afterwards', () => {
const loading = renderToStaticMarkup(
<ComposerActivity modelId="bonsai-27b" streamState="loading" progress={progress()} />,
);
expect(loading.match(/role="progressbar"/g)).toHaveLength(1);
expect(loading).not.toContain('Model transfer');
expect(loading).not.toContain('Load pipeline');
const ready = renderToStaticMarkup(
<ComposerActivity modelId="bonsai-27b" streamState="complete" progress={progress({ stage: 'ready' })} />,
);
expect(ready).toBe('');
});
});