Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

View File

@ -0,0 +1,587 @@
'use strict';
var assert = require('assert');
var fs = require('fs');
var path = require('path');
var ucs2 = require('punycode').ucs2;
var svgicons2svgfont = require('../src/index.js');
var StringDecoder = require('string_decoder').StringDecoder;
var svgiconsdir = require('../src/iconsdir');
var streamtest = require('streamtest');
var neatequal = require('neatequal');
var codepoint = require('./expected/test-codepoint.json');
// Helpers
function generateFontToFile(options, done, fileSuffix, startUnicode, files) { // eslint-disable-line
var dest = path.join(__dirname, 'results', options.fontName +
(fileSuffix || '') + '.svg');
var svgFontStream;
options.log = function() {};
svgFontStream = svgicons2svgfont(options);
svgFontStream.pipe(fs.createWriteStream(dest)).on('finish', function() {
assert.equal(
fs.readFileSync(
path.join(__dirname, 'expected',
options.fontName + (fileSuffix || '') + '.svg'),
{ encoding: 'utf8' }
),
fs.readFileSync(dest, { encoding: 'utf8' })
);
done();
});
svgiconsdir(
files || path.join(__dirname, 'fixtures', options.fontName), {
startUnicode: startUnicode || 0xE001,
}
)
.pipe(svgFontStream);
}
function generateFontToMemory(options, done, files, startUnicode) {
var content = '';
var decoder = new StringDecoder('utf8');
var svgFontStream;
options.log = function() {};
options.callback = function(glyphs) {
var fontName = options.fontName;
neatequal(glyphs, codepoint[fontName]);
};
svgFontStream = svgicons2svgfont(options);
svgFontStream.on('data', function(chunk) {
content += decoder.write(chunk);
});
svgFontStream.on('finish', function() {
assert.equal(
fs.readFileSync(
path.join(__dirname, 'expected', options.fontName + '.svg'),
{ encoding: 'utf8' }
),
content
);
done();
});
svgiconsdir(files || path.join(__dirname, 'fixtures', options.fontName), {
startUnicode: startUnicode || 0xE001,
})
.pipe(svgFontStream);
}
// Tests
describe('Generating fonts to files', function() {
it('should work for simple SVG', function(done) {
generateFontToFile({
fontName: 'originalicons',
}, done);
});
it('should work for simple fixedWidth and normalize option', function(done) {
generateFontToFile({
fontName: 'originalicons',
fixedWidth: true,
normalize: true,
}, done, 'n');
});
it('should work for simple SVG', function(done) {
generateFontToFile({
fontName: 'cleanicons',
}, done);
});
it('should work for simple SVG and custom ascent', function(done) {
generateFontToFile({
fontName: 'cleanicons',
ascent: 100,
}, done, '-ascent');
});
it('should work for simple SVG and custom properties', function(done) {
generateFontToFile({
fontName: 'cleanicons',
fontStyle: 'italic',
fontWeight: 'bold',
}, done, '-stw');
});
it('should work for codepoint mapped SVG icons', function(done) {
generateFontToFile({
fontName: 'prefixedicons',
callback: function() {},
}, done);
});
it('should work with multipath SVG icons', function(done) {
generateFontToFile({
fontName: 'multipathicons',
}, done);
});
it('should work with simple shapes SVG icons', function(done) {
generateFontToFile({
fontName: 'shapeicons',
}, done);
});
it('should work with variable height icons', function(done) {
generateFontToFile({
fontName: 'variableheighticons',
}, done);
});
it('should work with variable height icons and the normalize option', function(done) {
generateFontToFile({
fontName: 'variableheighticons',
normalize: true,
}, done, 'n');
});
it('should work with variable width icons', function(done) {
generateFontToFile({
fontName: 'variablewidthicons',
}, done);
});
it('should work with centered variable width icons and the fixed width option', function(done) {
generateFontToFile({
fontName: 'variablewidthicons',
fixedWidth: true,
centerHorizontally: true,
}, done, 'n');
});
it('should work with a font id', function(done) {
generateFontToFile({
fontName: 'variablewidthicons',
fixedWidth: true,
centerHorizontally: true,
fontId: 'plop',
}, done, 'id');
});
it('should not display hidden pathes', function(done) {
generateFontToFile({
fontName: 'hiddenpathesicons',
}, done);
});
it('should work with real world icons', function(done) {
generateFontToFile({
fontName: 'realicons',
}, done);
});
it('should work with rendering test SVG icons', function(done) {
generateFontToFile({
fontName: 'rendricons',
}, done);
});
it('should work with a single SVG icon', function(done) {
generateFontToFile({
fontName: 'singleicon',
}, done);
});
it('should work with transformed SVG icons', function(done) {
generateFontToFile({
fontName: 'transformedicons',
}, done);
});
it('should work when horizontally centering SVG icons', function(done) {
generateFontToFile({
fontName: 'tocentericons',
centerHorizontally: true,
}, done);
});
it('should work with a icons with path with fill none', function(done) {
generateFontToFile({
fontName: 'pathfillnone',
}, done);
});
it('should work with shapes with rounded corners', function(done) {
generateFontToFile({
fontName: 'roundedcorners',
}, done);
});
it('should work with a lot of icons', function(done) {
generateFontToFile({
fontName: 'lotoficons',
}, done, '', 0, [
'tests/fixtures/cleanicons/account.svg',
'tests/fixtures/cleanicons/arrow-down.svg',
'tests/fixtures/cleanicons/arrow-left.svg',
'tests/fixtures/cleanicons/arrow-right.svg',
'tests/fixtures/cleanicons/arrow-up.svg',
'tests/fixtures/cleanicons/basket.svg',
'tests/fixtures/cleanicons/close.svg',
'tests/fixtures/cleanicons/minus.svg',
'tests/fixtures/cleanicons/plus.svg',
'tests/fixtures/cleanicons/search.svg',
'tests/fixtures/hiddenpathesicons/sound--off.svg',
'tests/fixtures/hiddenpathesicons/sound--on.svg',
'tests/fixtures/multipathicons/kikoolol.svg',
'tests/fixtures/originalicons/mute.svg',
'tests/fixtures/originalicons/sound.svg',
'tests/fixtures/originalicons/speaker.svg',
'tests/fixtures/realicons/diegoliv.svg',
'tests/fixtures/realicons/hannesjohansson.svg',
'tests/fixtures/realicons/roelvanhitum.svg',
'tests/fixtures/realicons/safety-icon.svg',
'tests/fixtures/realicons/sb-icon.svg',
'tests/fixtures/realicons/settings-icon.svg',
'tests/fixtures/realicons/track-icon.svg',
'tests/fixtures/realicons/web-icon.svg',
'tests/fixtures/roundedcorners/roundedrect.svg',
'tests/fixtures/shapeicons/circle.svg',
'tests/fixtures/shapeicons/ellipse.svg',
'tests/fixtures/shapeicons/lines.svg',
'tests/fixtures/shapeicons/polygon.svg',
'tests/fixtures/shapeicons/polyline.svg',
'tests/fixtures/shapeicons/rect.svg',
'tests/fixtures/tocentericons/bottomleft.svg',
'tests/fixtures/tocentericons/center.svg',
'tests/fixtures/tocentericons/topright.svg',
]);
});
});
describe('Generating fonts to memory', function() {
it('should work for simple SVG', function(done) {
generateFontToMemory({
fontName: 'originalicons',
}, done);
});
it('should work for simple SVG', function(done) {
generateFontToMemory({
fontName: 'cleanicons',
}, done);
});
it('should work for codepoint mapped SVG icons', function(done) {
generateFontToMemory({
fontName: 'prefixedicons',
}, done);
});
it('should work with multipath SVG icons', function(done) {
generateFontToMemory({
fontName: 'multipathicons',
}, done);
});
it('should work with simple shapes SVG icons', function(done) {
generateFontToMemory({
fontName: 'shapeicons',
}, done);
});
});
describe('Using options', function() {
it('should work with fixedWidth option set to true', function(done) {
generateFontToFile({
fontName: 'originalicons',
fixedWidth: true,
}, done, '2');
});
it('should work with custom fontHeight option', function(done) {
generateFontToFile({
fontName: 'originalicons',
fontHeight: 800,
}, done, '3');
});
it('should work with custom descent option', function(done) {
generateFontToFile({
fontName: 'originalicons',
descent: 200,
}, done, '4');
});
it('should work with fixedWidth set to true and with custom fontHeight option',
function(done) {
generateFontToFile({
fontName: 'originalicons',
fontHeight: 800,
fixedWidth: true,
}, done, '5');
}
);
it('should work with fixedWidth and centerHorizontally set to true and with' +
' custom fontHeight option', function(done) {
generateFontToFile({
fontName: 'originalicons',
fontHeight: 800,
fixedWidth: true,
centerHorizontally: true,
}, done, '6');
});
it('should work with fixedWidth, normalize and centerHorizontally set to' +
' true and with custom fontHeight option', function(done) {
generateFontToFile({
fontName: 'originalicons',
fontHeight: 800,
normalize: true,
fixedWidth: true,
centerHorizontally: true,
}, done, '7');
});
it('should work with nested icons', function(done) {
generateFontToFile({
fontName: 'nestedicons',
}, done, '', 0xEA01);
});
});
describe('Passing code points', function() {
it('should work with multiple unicode values for a single icon', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
var svgFontStream = svgicons2svgfont();
var content = '';
var decoder = new StringDecoder('utf8');
svgIconStream.metadata = {
name: 'account',
unicode: ['\uE001', '\uE002'],
};
svgFontStream.on('data', function(chunk) {
content += decoder.write(chunk);
});
svgFontStream.on('finish', function() {
assert.equal(
fs.readFileSync(path.join(__dirname, 'expected', 'cleanicons-multi.svg'),
{ encoding: 'utf8' }),
content
);
done();
});
svgFontStream.write(svgIconStream);
svgFontStream.end();
});
it('should work with ligatures', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
var svgFontStream = svgicons2svgfont();
var content = '';
var decoder = new StringDecoder('utf8');
svgIconStream.metadata = {
name: 'account',
unicode: ['\uE001\uE002'],
};
svgFontStream.on('data', function(chunk) {
content += decoder.write(chunk);
});
svgFontStream.on('finish', function() {
assert.equal(
fs.readFileSync(path.join(__dirname, 'expected', 'cleanicons-lig.svg'),
{ encoding: 'utf8' }),
content
);
done();
});
svgFontStream.write(svgIconStream);
svgFontStream.end();
});
it('should work with high code points', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
var svgFontStream = svgicons2svgfont();
var content = '';
var decoder = new StringDecoder('utf8');
svgIconStream.metadata = {
name: 'account',
unicode: [ucs2.encode([0x1F63A])],
};
svgFontStream.on('data', function(chunk) {
content += decoder.write(chunk);
});
svgFontStream.on('finish', function() {
assert.equal(
fs.readFileSync(path.join(__dirname, 'expected', 'cleanicons-high.svg'),
{ encoding: 'utf8' }),
content
);
done();
});
svgFontStream.write(svgIconStream);
svgFontStream.end();
});
});
describe('Providing bad glyphs', function() {
it('should fail when not providing glyph name', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
svgIconStream.metadata = {
unicode: '\uE001',
};
svgicons2svgfont().on('error', function(err) {
assert.equal(err instanceof Error, true);
assert.equal(err.message, 'Please provide a name for the glyph at index 0');
done();
}).write(svgIconStream);
});
it('should fail when not providing codepoints', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
svgIconStream.metadata = {
name: 'test',
};
svgicons2svgfont().on('error', function(err) {
assert.equal(err instanceof Error, true);
assert.equal(err.message, 'Please provide a codepoint for the glyph "test"');
done();
}).write(svgIconStream);
});
it('should fail when providing unicode value with duplicates', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
svgIconStream.metadata = {
name: 'test',
unicode: ['\uE002', '\uE002'],
};
svgicons2svgfont().on('error', function(err) {
assert.equal(err instanceof Error, true);
assert.equal(err.message, 'Given codepoints for the glyph "test" contain duplicates.');
done();
}).write(svgIconStream);
});
it('should fail when providing the same codepoint twice', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
var svgIconStream2 = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
var svgFontStream = svgicons2svgfont();
svgIconStream.metadata = {
name: 'test',
unicode: '\uE002',
};
svgIconStream2.metadata = {
name: 'test2',
unicode: '\uE002',
};
svgFontStream.on('error', function(err) {
assert.equal(err instanceof Error, true);
assert.equal(err.message, 'The glyph "test2" codepoint seems to be used already elsewhere.');
done();
});
svgFontStream.write(svgIconStream);
svgFontStream.write(svgIconStream2);
});
it('should fail when providing the same name twice', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
var svgIconStream2 = fs.createReadStream(
path.join(__dirname, 'fixtures', 'cleanicons', 'account.svg')
);
var svgFontStream = svgicons2svgfont();
svgIconStream.metadata = {
name: 'test',
unicode: '\uE001',
};
svgIconStream2.metadata = {
name: 'test',
unicode: '\uE002',
};
svgFontStream.on('error', function(err) {
assert.equal(err instanceof Error, true);
assert.equal(err.message, 'The glyph name "test" must be unique.');
done();
});
svgFontStream.write(svgIconStream);
svgFontStream.write(svgIconStream2);
});
it('should fail when providing bad pathdata', function(done) {
var svgIconStream = fs.createReadStream(
path.join(__dirname, 'fixtures', 'badicons', 'pathdata.svg')
);
svgIconStream.metadata = {
name: 'test',
unicode: ['\uE002'],
};
svgicons2svgfont().on('error', function(err) {
assert.equal(err instanceof Error, true);
assert.equal(err.message, 'Got an error parsing the glyph "test":' +
' Expected a flag, got "120" at index "23".');
done();
}).on('end', function() {
done();
}).write(svgIconStream);
});
it('should fail when providing bad XML', function(done) {
var svgIconStream = streamtest.v2.fromChunks(['bad', 'xml']);
svgIconStream.metadata = {
name: 'test',
unicode: ['\uE002'],
};
svgicons2svgfont().on('error', function(err) {
assert.equal(err instanceof Error, true);
assert.equal(err.message, 'Non-whitespace before first tag.\nLine: 0\nColumn: 1\nChar: b');
done();
}).write(svgIconStream);
});
});