import { describe, it, expect, beforeEach, vi } from 'vitest' import { createHistogramDownloadConfig } from './download' import type { HistogramWidgetData } from './types' const data: HistogramWidgetData = [ [1, 2, 3], [4, 5, 6], ] const ticks = [0, 10, 20, 30] let csvText = '' beforeEach(() => { csvText = '' vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock') vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined) const RealBlob = global.Blob vi.stubGlobal( 'Blob', class extends RealBlob { constructor(parts: BlobPart[], opts?: BlobPropertyBag) { csvText = typeof parts[0] === 'string' ? parts[0] : '' super(parts, opts) } }, ) }) describe('createHistogramDownloadConfig', () => { it('CSV-only by default', () => { const items = createHistogramDownloadConfig({ filename: 'h', getData: () => data, getTicks: () => ticks, }) expect(items.map((i) => i.id)).toEqual(['csv']) }) it('prepends PNG when getCaptureEl is provided', () => { const items = createHistogramDownloadConfig({ filename: 'h', getData: () => data, getTicks: () => ticks, getCaptureEl: () => document.createElement('div'), }) expect(items.map((i) => i.id)).toEqual(['png', 'csv']) }) it('CSV resolve serialises bins × series with default series names', async () => { const items = createHistogramDownloadConfig({ filename: 'h', getData: () => data, getTicks: () => ticks, }) const handle = await items.find((i) => i.id === 'csv')!.resolve() expect(handle.filename).toBe('h.csv') expect(csvText).toBe( 'bin_low,bin_high,series_1,series_2\n0,10,1,4\n10,20,2,5\n20,30,3,6', ) }) it('CSV honours supplied seriesNames', async () => { const items = createHistogramDownloadConfig({ filename: 'h', getData: () => data, getTicks: () => ticks, seriesNames: ['lo', 'hi'], }) await items.find((i) => i.id === 'csv')!.resolve() expect(csvText.startsWith('bin_low,bin_high,lo,hi')).toBe(true) }) it('CSV emits header-only when ticks has < 2 entries', async () => { const items = createHistogramDownloadConfig({ filename: 'h', getData: () => data, getTicks: () => [0], }) await items.find((i) => i.id === 'csv')!.resolve() expect(csvText).toBe('bin_low,bin_high,series_1,series_2') }) it('CSV fills missing series values with 0', async () => { const sparse: HistogramWidgetData = [[1, 2, 3], []] const items = createHistogramDownloadConfig({ filename: 'h', getData: () => sparse, getTicks: () => ticks, }) await items.find((i) => i.id === 'csv')!.resolve() expect(csvText).toContain('0,10,1,0') expect(csvText).toContain('10,20,2,0') }) })