import { IconifyIconBuildResult } from '../lib/svg/build'; import { parseSVGContent, buildParsedSVG, convertParsedSVG, } from '../lib/svg/parse'; import { splitSVGDefs } from '../lib/svg/defs'; import { getSVGViewBox } from '../lib/svg/viewbox'; import { readFileSync } from 'node:fs'; import { IconifyIcon } from '@iconify/types'; const fixturesDir = './tests/fixtures'; describe('Testing parsing SVG content', () => { test('Getting viewBox', () => { // Valid numbers expect(getSVGViewBox('1 2 3 4')).toEqual([1, 2, 3, 4]); expect(getSVGViewBox('-1 0 25.5 -123.5')).toEqual([ -1, 0, 25.5, -123.5, ]); expect(getSVGViewBox(' 1\t2 3\n4\t ')).toEqual([1, 2, 3, 4]); // Bad numbers expect(getSVGViewBox('1 2 3')).toBeUndefined(); expect(getSVGViewBox('1 2 3 4 5')).toBeUndefined(); expect(getSVGViewBox('a 1 2 3')).toBeUndefined(); expect(getSVGViewBox('0 1 2 b')).toBeUndefined(); expect(getSVGViewBox('1 2 3 4b')).toBeUndefined(); }); test('Simple SVG', () => { const body = ''; const svg = `${body}`; // Parse const parsed = parseSVGContent(svg); expect(parsed).toBeTruthy(); if (!parsed) { return; } expect(parsed.attribs).toEqual({ width: '24', height: '24', viewBox: '0 0 24 24', xmlns: 'http://www.w3.org/2000/svg', }); expect(parsed.body).toEqual(body); // Build const built = buildParsedSVG(parsed); const expected: IconifyIconBuildResult = { attributes: { width: '24', height: '24', viewBox: '0 0 24 24', }, viewBox: [0, 0, 24, 24], body, }; expect(built).toEqual(expected); const icon = convertParsedSVG(parsed); const expectedIcon: IconifyIcon = { left: 0, top: 0, width: 24, height: 24, body, }; expect(icon).toEqual(expectedIcon); // Defs expect(splitSVGDefs(body)).toEqual({ defs: '', content: body, }); }); test('SVG with XML heading', () => { const svg = readFileSync( fixturesDir + '/circle-xml-preface.svg', 'utf8' ); const body = ''; // Parse const parsed = parseSVGContent(svg); expect(parsed).toBeTruthy(); if (!parsed) { return; } expect(parsed?.attribs).toEqual({ viewBox: '0 0 120 120', xmlns: 'http://www.w3.org/2000/svg', }); expect(parsed.body).toEqual(body); // Build const built = buildParsedSVG(parsed); const expected: IconifyIconBuildResult = { attributes: { viewBox: '0 0 120 120', }, viewBox: [0, 0, 120, 120], body, }; expect(built).toEqual(expected); // Defs expect(splitSVGDefs(body)).toEqual({ defs: '', content: body, }); }); test('SVG with style and junk', () => { const body1 = 'image/svg+xml'; const defs1 = ''; const body2 = ''; const body = `${body1}${defs1}${body2}`; const svg = ` ${body} `; // Parse const parsed = parseSVGContent(svg); expect(parsed).toBeTruthy(); if (!parsed) { return; } expect(parsed?.attribs).toEqual({ 'xmlns:dc': 'http://purl.org/dc/elements/1.1/', 'xmlns:cc': 'http://creativecommons.org/ns#', 'xmlns:rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'xmlns:svg': 'http://www.w3.org/2000/svg', 'xmlns': 'http://www.w3.org/2000/svg', 'viewBox': '0 -1 47.5 49.5', 'style': 'enable-background:new 0 -1 47.5 49.5;', 'xml:space': 'preserve', 'version': '1.1', 'id': 'svg2', }); expect(parsed.body).toEqual(body); // Build const built = buildParsedSVG(parsed); const expected: IconifyIconBuildResult = { attributes: { viewBox: '0 -1 47.5 49.5', }, viewBox: [0, -1, 47.5, 49.5], body: `${defs1}${body1}${body2}`, }; expect(built).toEqual(expected); const icon = convertParsedSVG(parsed); const expectedIcon: IconifyIcon = { left: 0, top: -1, width: 47.5, height: 49.5, body: expected.body, }; expect(icon).toEqual(expectedIcon); // Defs expect(splitSVGDefs(body)).toEqual({ defs: defs1, content: body1 + body2, }); }); test('SVG with fill', () => { const body = ` `; const svg = `${body}`; // Parse const parsed = parseSVGContent(svg); expect(parsed).toBeTruthy(); if (!parsed) { return; } expect(parsed?.attribs).toEqual({ width: '32', height: '32', viewBox: '0 0 32 32', fill: 'none', xmlns: 'http://www.w3.org/2000/svg', }); expect(parsed.body).toEqual(body.trim()); // Build const built = buildParsedSVG(parsed); const expected: IconifyIconBuildResult = { attributes: { width: '32', height: '32', viewBox: '0 0 32 32', }, viewBox: [0, 0, 32, 32], body: `${body.trim()}`, }; expect(built).toEqual(expected); }); test('Nested SVG', () => { const body = ` `; const parsed = parseSVGContent(` ${body} `); expect(parsed).toBeTruthy(); if (!parsed) { return; } expect(parsed.attribs).toEqual({ viewBox: '0 0 300 100', xmlns: 'http://www.w3.org/2000/svg', stroke: 'red', fill: 'grey', }); expect(parsed.body).toEqual(body); }); });