UNPKG

@julesl23/s5js

Version:

Enhanced TypeScript SDK for S5 decentralized storage with path-based API, media processing, and directory utilities

181 lines 7.77 kB
import { describe, it, expect } from 'vitest'; import { WASMModule } from '../../src/media/wasm/module.js'; describe('WASMModule', () => { describe('initialization', () => { it('should be a class with required methods', () => { expect(WASMModule).toBeDefined(); expect(typeof WASMModule.initialize).toBe('function'); }); it('should initialize WebAssembly module', async () => { const module = await WASMModule.initialize(); expect(module).toBeDefined(); expect(module.extractMetadata).toBeDefined(); expect(module.cleanup).toBeDefined(); }); it('should track loading progress', async () => { const progressValues = []; await WASMModule.initialize({ onProgress: (percent) => progressValues.push(percent) }); expect(progressValues.length).toBeGreaterThan(0); expect(progressValues[0]).toBe(0); expect(progressValues[progressValues.length - 1]).toBe(100); // Verify progress increases monotonically for (let i = 1; i < progressValues.length; i++) { expect(progressValues[i]).toBeGreaterThanOrEqual(progressValues[i - 1]); } }); it('should handle custom WASM URL', async () => { const customUrl = './custom-media.wasm'; const module = await WASMModule.initialize({ wasmUrl: customUrl }); expect(module).toBeDefined(); }); }); describe('memory management', () => { it('should allocate and free memory correctly', async () => { const module = await WASMModule.initialize(); // Test allocating memory for image data const testData = new Uint8Array([0x89, 0x50, 0x4E, 0x47]); // PNG header const metadata = module.extractMetadata(testData); // Should not throw module.cleanup(); }); it('should track allocated buffers', async () => { const module = await WASMModule.initialize(); // Extract metadata multiple times const data1 = new Uint8Array(100); const data2 = new Uint8Array(200); module.extractMetadata(data1); module.extractMetadata(data2); // Cleanup should free all allocated buffers module.cleanup(); // Should be safe to call cleanup multiple times module.cleanup(); }); it('should handle memory limits gracefully', async () => { const module = await WASMModule.initialize(); // Try to allocate a very large buffer (should handle gracefully) const largeData = new Uint8Array(100 * 1024 * 1024); // 100MB // Should either succeed or return undefined, not crash const metadata = module.extractMetadata(largeData); if (metadata) { expect(metadata).toHaveProperty('width'); expect(metadata).toHaveProperty('height'); } module.cleanup(); }); }); describe('metadata extraction', () => { let module; beforeAll(async () => { module = await WASMModule.initialize(); }); afterAll(() => { module.cleanup(); }); it('should detect PNG format', async () => { // PNG magic bytes const pngHeader = new Uint8Array([ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ]); const metadata = module.extractMetadata(pngHeader); expect(metadata).toBeDefined(); if (metadata) { expect(metadata.format).toBe('png'); } }); it('should detect JPEG format', async () => { // JPEG magic bytes const jpegHeader = new Uint8Array([ 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46 ]); const metadata = module.extractMetadata(jpegHeader); expect(metadata).toBeDefined(); if (metadata) { expect(metadata.format).toBe('jpeg'); } }); it('should detect WebP format', async () => { // WebP magic bytes (RIFF....WEBP) const webpHeader = new Uint8Array([ 0x52, 0x49, 0x46, 0x46, // RIFF 0x00, 0x00, 0x00, 0x00, // file size (placeholder) 0x57, 0x45, 0x42, 0x50 // WEBP ]); const metadata = module.extractMetadata(webpHeader); expect(metadata).toBeDefined(); if (metadata) { expect(metadata.format).toBe('webp'); } }); it('should return undefined for non-image data', async () => { const textData = new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello" const metadata = module.extractMetadata(textData); expect(metadata).toBeUndefined(); }); it('should extract image dimensions', async () => { // Use a minimal valid PNG for testing const pngData = createMinimalPNG(); const metadata = module.extractMetadata(pngData); expect(metadata).toBeDefined(); if (metadata) { expect(typeof metadata.width).toBe('number'); expect(typeof metadata.height).toBe('number'); expect(metadata.width).toBeGreaterThan(0); expect(metadata.height).toBeGreaterThan(0); } }); }); describe('error handling', () => { it('should handle initialization errors gracefully', async () => { // Force an error by using invalid URL const module = await WASMModule.initialize({ wasmUrl: 'invalid://url' }); // Should fallback gracefully expect(module).toBeDefined(); expect(module.extractMetadata).toBeDefined(); }); it('should handle corrupt image data', async () => { const module = await WASMModule.initialize(); const corruptData = new Uint8Array([0xFF, 0xFF, 0xFF, 0xFF]); const metadata = module.extractMetadata(corruptData); // Should return undefined or minimal metadata if (metadata) { expect(metadata.format).toBeDefined(); } module.cleanup(); }); it('should handle empty data', async () => { const module = await WASMModule.initialize(); const emptyData = new Uint8Array(0); const metadata = module.extractMetadata(emptyData); expect(metadata).toBeUndefined(); module.cleanup(); }); }); }); // Helper function to create a minimal valid PNG function createMinimalPNG() { // This creates a minimal 1x1 transparent PNG return new Uint8Array([ // PNG header 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, // IHDR chunk 0x00, 0x00, 0x00, 0x0D, // chunk length 0x49, 0x48, 0x44, 0x52, // "IHDR" 0x00, 0x00, 0x00, 0x01, // width: 1 0x00, 0x00, 0x00, 0x01, // height: 1 0x08, 0x06, // bit depth: 8, color type: 6 (RGBA) 0x00, 0x00, 0x00, // compression, filter, interlace 0x1F, 0x15, 0xC4, 0x89, // CRC // IDAT chunk (compressed image data) 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9C, 0x62, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, // IEND chunk 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 ]); } //# sourceMappingURL=wasm-module.test.js.map