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 = ``;
// 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 = `
`;
// 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 = ``;
// 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(`
`);
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);
});
});