|
| 1 | +import { describe, expect, it } from 'vitest'; |
| 2 | + |
| 3 | +import { createWorkbook } from '../factory.js'; |
| 4 | +import { createExcelFileStream } from '../streaming.js'; |
| 5 | +import { Worksheet } from '../Excel/Worksheet.js'; |
| 6 | + |
| 7 | +// Basic streaming test for NodeJS and browser-like environments |
| 8 | + |
| 9 | +describe('Streaming API', () => { |
| 10 | + it('should stream Excel file chunks', async () => { |
| 11 | + const workbook = createWorkbook(); |
| 12 | + const worksheet = workbook.createWorksheet({ name: 'Sheet1' }); |
| 13 | + worksheet.setData([ |
| 14 | + ['Artist', 'Album', 'Price'], |
| 15 | + ['Buckethead', 'Albino Slug', 8.99], |
| 16 | + ['Crystal Method', 'Vegas', 10.54], |
| 17 | + ]); |
| 18 | + workbook.addWorksheet(worksheet); |
| 19 | + |
| 20 | + const chunks: Uint8Array[] = []; |
| 21 | + for await (const chunk of createExcelFileStream(workbook, { chunkSize: 1024 })) { |
| 22 | + expect(chunk).toBeInstanceOf(Uint8Array); |
| 23 | + chunks.push(chunk); |
| 24 | + } |
| 25 | + // Should produce a non-empty file |
| 26 | + const totalSize = chunks.reduce((sum, c) => sum + c.length, 0); |
| 27 | + expect(totalSize).toBeGreaterThan(0); |
| 28 | + }); |
| 29 | + |
| 30 | + it('should stream Excel file with formulas and styles', async () => { |
| 31 | + const workbook = createWorkbook(); |
| 32 | + const worksheet = workbook.createWorksheet({ name: 'Sheet2' }); |
| 33 | + worksheet.setData([ |
| 34 | + [{ value: 'Artist' }, { value: 'Price' }, { value: 'Total' }], |
| 35 | + ['Buckethead', 8.99, { value: 'B2*2', metadata: { type: 'formula' } }], |
| 36 | + ['Crystal Method', 10.54, { value: 'B3*2', metadata: { type: 'formula' } }], |
| 37 | + ]); |
| 38 | + workbook.addWorksheet(worksheet); |
| 39 | + |
| 40 | + const chunks: Uint8Array[] = []; |
| 41 | + for await (const chunk of createExcelFileStream(workbook, { chunkSize: 512 })) { |
| 42 | + expect(chunk).toBeInstanceOf(Uint8Array); |
| 43 | + chunks.push(chunk); |
| 44 | + } |
| 45 | + const totalSize = chunks.reduce((sum, c) => sum + c.length, 0); |
| 46 | + expect(totalSize).toBeGreaterThan(0); |
| 47 | + }); |
| 48 | + |
| 49 | + describe('Worksheet XML helpers', () => { |
| 50 | + it('getWorksheetXmlHeader returns correct header', () => { |
| 51 | + const ws = new Worksheet({ name: 'Test' }); |
| 52 | + const header = ws.getWorksheetXmlHeader(); |
| 53 | + expect(header).toContain('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'); |
| 54 | + expect(header).toContain('<worksheet'); |
| 55 | + expect(header).toContain('xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"'); |
| 56 | + }); |
| 57 | + |
| 58 | + it('getWorksheetXmlFooter returns empty string if no header/footer', () => { |
| 59 | + const ws = new Worksheet({ name: 'Test' }); |
| 60 | + expect(ws.getWorksheetXmlFooter()).toBe(''); |
| 61 | + }); |
| 62 | + |
| 63 | + it('getWorksheetXmlFooter returns headerFooter XML if header/footer set', () => { |
| 64 | + const ws = new Worksheet({ name: 'Test' }); |
| 65 | + ws.setHeader(['Left', 'Center', 'Right']); |
| 66 | + ws.setFooter(['FLeft', 'FCenter', 'FRight']); |
| 67 | + const xml = ws.getWorksheetXmlFooter(); |
| 68 | + expect(xml).toContain('<headerFooter>'); |
| 69 | + expect(xml).toContain('<oddHeader>'); |
| 70 | + expect(xml).toContain('<oddFooter>'); |
| 71 | + expect(xml).toContain('Left'); |
| 72 | + expect(xml).toContain('FLeft'); |
| 73 | + }); |
| 74 | + }); |
| 75 | + |
| 76 | + describe('serializeRows', () => { |
| 77 | + it('serializes text and number rows correctly', () => { |
| 78 | + const ws = new Worksheet({ name: 'Test' }); |
| 79 | + ws.sharedStrings = { strings: {}, addString: () => 0 } as any; |
| 80 | + const rows = [ |
| 81 | + ['Header1', 'Header2'], |
| 82 | + [123, 'abc'], |
| 83 | + ]; |
| 84 | + const xml = ws.serializeRows(rows); |
| 85 | + expect(xml).toContain('<row r="1">'); |
| 86 | + expect(xml).toContain('<c r="A1" t="s"><v>0</v></c>'); |
| 87 | + expect(xml).toContain('<c r="B2" t="s"><v>0</v></c>'); |
| 88 | + }); |
| 89 | + |
| 90 | + it('serializes formula cells', () => { |
| 91 | + const ws = new Worksheet({ name: 'Test' }); |
| 92 | + ws.sharedStrings = { strings: {}, addString: () => 0 } as any; |
| 93 | + const rows = [ |
| 94 | + ['Header1', 'Header2'], |
| 95 | + [{ value: 'A2+B2', metadata: { type: 'formula' } }, 42], |
| 96 | + ]; |
| 97 | + const xml = ws.serializeRows(rows); |
| 98 | + expect(xml).toContain('<c r="A2" t="s"><v>0</v></c>'); |
| 99 | + expect(xml).toContain('<c r="B2"><v>42</v></c>'); |
| 100 | + }); |
| 101 | + }); |
| 102 | +}); |
0 commit comments