scratch-svg-renderer/test/fixup-svg-string.js
2021-01-09 00:20:11 -05:00

144 lines
5.2 KiB
JavaScript

const test = require('tap').test;
const fs = require('fs');
const path = require('path');
const DOMParser = require('xmldom').DOMParser;
const fixupSvgString = require('../src/fixup-svg-string');
// The browser DOMParser throws on errors by default, replicate that here
// by customizing the error callback to throw (defaults to logging)
const domParser = new DOMParser({
errorHandler: {
error: e => {
throw new Error(e);
}
}
});
test('fixupSvgString should make parsing fixtures not throw', t => {
const filePath = path.resolve(__dirname, './fixtures/hearts.svg');
const svgString = fs.readFileSync(filePath)
.toString();
const fixed = fixupSvgString(svgString);
// Make sure undefineds aren't being written into the file
t.equal(fixed.indexOf('undefined'), -1);
t.notThrow(() => {
domParser.parseFromString(fixed, 'text/xml');
});
t.end();
});
test('fixupSvgString should correct namespace declarations bound to reserved namespace names', t => {
const filePath = path.resolve(__dirname, './fixtures/reserved-namespace.svg');
const svgString = fs.readFileSync(filePath)
.toString();
const fixed = fixupSvgString(svgString);
// Make sure undefineds aren't being written into the file
t.equal(fixed.indexOf('undefined'), -1);
t.notThrow(() => {
domParser.parseFromString(fixed, 'text/xml');
});
t.end();
});
test('fixupSvgString shouldn\'t correct non-attributes', t => {
const dontFix = fixupSvgString('<text>xmlns:test="http://www/w3.org/XML/1998/namespace" is not an xmlns attribute</text>');
t.notEqual(dontFix.indexOf('http://www/w3.org/XML/1998/namespace'), -1);
t.end();
});
test('fixupSvgString should strip `svg:` prefix from tag names', t => {
const filePath = path.resolve(__dirname, './fixtures/svg-tag-prefixes.svg');
const svgString = fs.readFileSync(filePath)
.toString();
const fixed = fixupSvgString(svgString);
const checkPrefixes = element => {
t.notEqual(element.prefix, 'svg');
// JSDOM doesn't have element.children, only element.childNodes
if (element.childNodes) {
// JSDOM's childNodes is not iterable, so for...of cannot be used here
for (let i = 0; i < element.childNodes.length; i++) {
const child = element.childNodes[i];
if (child.nodeType === 1 /* Node.ELEMENT_NODE */) checkPrefixes(child);
}
}
};
// Make sure undefineds aren't being written into the file
t.equal(fixed.indexOf('undefined'), -1);
t.notThrow(() => {
domParser.parseFromString(fixed, 'text/xml');
});
checkPrefixes(domParser.parseFromString(fixed, 'text/xml'));
t.end();
});
test('fixupSvgString should empty script tags', t => {
const filePath = path.resolve(__dirname, './fixtures/script.svg');
const svgString = fs.readFileSync(filePath)
.toString();
const fixed = fixupSvgString(svgString);
// Script tag should remain but have no contents.
t.equals(fixed.indexOf('<script></script>'), 207);
// The contents of the script tag (e.g. the alert) are no longer there.
t.equals(fixed.indexOf('stuff inside'), -1);
t.end();
});
test('fixupSvgString should empty script tags in onload', t => {
const filePath = path.resolve(__dirname, './fixtures/onload-script.svg');
const svgString = fs.readFileSync(filePath)
.toString();
const fixed = fixupSvgString(svgString);
// Script tag should remain but have no contents.
t.equals(fixed.indexOf('<script></script>'), 792);
t.end();
});
test('fixupSvgString strips contents of metadata', t => {
const filePath = path.resolve(__dirname, './fixtures/metadata-body.svg');
const svgString = fs.readFileSync(filePath)
.toString();
const fixed = fixupSvgString(svgString);
// Metadata tag should still exist, it'll just be empty.
t.equals(fixed.indexOf('<metadata></metadata>'), 207);
// The contents of the metadata tag are gone.
t.equals(fixed.indexOf('stuff inside'), -1);
t.end();
});
test('fixupSvgString strips contents of metadata in onload', t => {
const filePath = path.resolve(__dirname, './fixtures/metadata-onload.svg');
const svgString = fs.readFileSync(filePath)
.toString();
const fixed = fixupSvgString(svgString);
// Metadata tag should still exist, it'll just be empty.
t.equals(fixed.indexOf('<metadata></metadata>'), 800);
t.end();
});
test('fixupSvgString should correct invalid mime type', t => {
const filePath = path.resolve(__dirname, './fixtures/invalid-cloud.svg');
const svgString = fs.readFileSync(filePath, 'utf8');
const fixed = fixupSvgString(svgString);
// Make sure we replace an invalid mime type from Photoshop exported SVGs
t.notEqual(svgString.indexOf('img/png'), -1);
t.equal(fixed.indexOf('img/png'), -1);
t.notThrow(() => {
domParser.parseFromString(fixed, 'text/xml');
});
t.end();
});
test('fixupSvgString shouldn\'t correct non-image tags', t => {
const dontFix = fixupSvgString('<text>data:img/png is not a mime type</text>');
t.notEqual(dontFix.indexOf('img/png'), -1);
t.end();
});