H4 + H2 formatter half: carry raw numbers across the progress boundary
Closes H4 and the remaining formatter half of H2. - New @shared/format.ts is the single home for fmtBytes/fmtSpeed/fmtEta, imported by both main and renderer. main/lib/formatters.ts re-exports them. - DownloadProgress now carries raw speedBytesPerSec/etaSeconds instead of pre-formatted speed/eta strings. main's parseProgress emits the raw numbers. - The renderer stores the raw numbers on DownloadItem; QueueItem formats them for per-item display, and summarizeQueue sums/maxes them directly. The lossy string->number->string round-trip in queueStats (parseSpeed / parseEtaSeconds / a local formatSpeed / formatEta) is deleted, along with a duplicate fmtEta in store/downloads.ts. - Per-item and aggregate speed now use the same 1024-based scale; the aggregate previously used a 1000-based formatter (a latent inconsistency). Tests updated for the raw-number contract (parseProgress, summarizeQueue). typecheck + 248 tests + eslint + prettier green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+12
-6
@@ -48,19 +48,25 @@ describe('summarizeQueue', () => {
|
||||
expect(s.progress).toBeCloseTo(0.4, 5)
|
||||
})
|
||||
|
||||
it('sums download speeds across MB/s and MiB/s strings', () => {
|
||||
it('sums raw download rates into one formatted label', () => {
|
||||
const MB = 1024 * 1024
|
||||
const s = summarizeQueue([
|
||||
item({ status: 'downloading', progress: 0.1, speed: '4.0 MB/s' }),
|
||||
item({ status: 'downloading', progress: 0.1, speed: '2000 KiB/s' })
|
||||
item({ status: 'downloading', progress: 0.1, speedBytesPerSec: 4 * MB }),
|
||||
item({ status: 'downloading', progress: 0.1, speedBytesPerSec: 2 * MB })
|
||||
])
|
||||
// 4.0 MB/s + ~2.0 MB/s ≈ 6.0 MB/s
|
||||
// 4 MB/s + 2 MB/s = 6 MB/s
|
||||
expect(s.speedLabel).toBe('6.0 MB/s')
|
||||
})
|
||||
|
||||
it('leaves the speed label empty when no item reports a rate', () => {
|
||||
const s = summarizeQueue([item({ status: 'downloading', progress: 0.1 })])
|
||||
expect(s.speedLabel).toBe('')
|
||||
})
|
||||
|
||||
it('reports the longest active ETA as the time left', () => {
|
||||
const s = summarizeQueue([
|
||||
item({ status: 'downloading', progress: 0.5, eta: '0:30' }),
|
||||
item({ status: 'downloading', progress: 0.2, eta: '2:10' })
|
||||
item({ status: 'downloading', progress: 0.5, etaSeconds: 30 }),
|
||||
item({ status: 'downloading', progress: 0.2, etaSeconds: 130 })
|
||||
])
|
||||
expect(s.etaLabel).toBe('2:10')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user