Skip to content

Commit c7bf8d3

Browse files
committed
fix(icons-to-woff.js): enforce deterministic output
Ensure builds with the same set of inputs results in an identical font hash for deterministic builds. re #53
1 parent 0de5bd2 commit c7bf8d3

File tree

3 files changed

+80
-5
lines changed

3 files changed

+80
-5
lines changed

lib/icons-to-woff.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ module.exports = function createIconFont (fs, icons, options) {
2121
name: options.name,
2222
normalize: true,
2323
fontHeight: options.enforcedSvgHeight ? options.enforcedSvgHeight : undefined,
24-
log: function () {},
25-
error: /** @param {any} err */function (err) {
26-
reject(err);
27-
}
24+
log: function () {}
2825
});
2926
let svgFont = '';
3027
fontStream
@@ -58,7 +55,7 @@ module.exports = function createIconFont (fs, icons, options) {
5855
});
5956
fontStream.end();
6057
})
61-
.then((svgFont) => svg2ttf(svgFont, {}).buffer)
58+
.then((svgFont) => svg2ttf(svgFont, { ts: 0 }).buffer)
6259
.then((ttfFont) => ttf2woff(ttfFont).buffer)
6360
.then((woffFont) => Buffer.from(woffFont).toString('base64'));
6461
};

test/fixtures/malformed.svg

Lines changed: 1 addition & 0 deletions
Loading

test/icons-to-woff.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use strict';
2+
/* eslint max-len: off, quotes:off, arrow-parens:off */
3+
import createIconFont from '../lib/icons-to-woff.js';
4+
import fs from 'fs';
5+
import test from 'ava';
6+
7+
test('should throw an error when an svg cannot be found', async (t) => {
8+
let error;
9+
try {
10+
await createIconFont(fs, [
11+
'./test/fixtures/does-not-exist.svg'
12+
], {
13+
name: 'test'
14+
});
15+
} catch (e) {
16+
error = e.message;
17+
}
18+
19+
t.is(error.substring(0, 33), 'ENOENT: no such file or directory');
20+
t.pass();
21+
});
22+
23+
test('should throw an error when no glyph name is provided', async (t) => {
24+
let error;
25+
try {
26+
await createIconFont(fs, [
27+
'./test/fixtures/malformed.svg'
28+
], {
29+
name: 'test'
30+
});
31+
} catch (e) {
32+
error = e.message;
33+
}
34+
35+
t.is(error.substring(0, 32), 'Non-whitespace before first tag.');
36+
t.pass();
37+
});
38+
39+
test('should produce the same output when receiving the same input and configuration', async (t) => {
40+
const svgs = [
41+
'./test/fixtures/account-494x512.svg',
42+
'./test/fixtures/account-986x1024.svg'
43+
];
44+
45+
const test1 = await createIconFont(fs, svgs, {
46+
name: 'test'
47+
});
48+
49+
await new Promise((resolve) => setTimeout(resolve, 1000));
50+
51+
const test2 = await createIconFont(fs, svgs, {
52+
name: 'test'
53+
});
54+
55+
t.is(test1, test2);
56+
t.pass();
57+
});
58+
59+
test('should produce different output when receiving the same input but different fontHeight', async (t) => {
60+
const svgs = [
61+
'./test/fixtures/account-494x512.svg',
62+
'./test/fixtures/account-986x1024.svg'
63+
];
64+
65+
const test1 = await createIconFont(fs, svgs, {
66+
enforcedSvgHeight: 32
67+
});
68+
69+
await new Promise((resolve) => setTimeout(resolve, 1000));
70+
71+
const test2 = await createIconFont(fs, svgs, {
72+
enforcedSvgHeight: 16
73+
});
74+
75+
t.not(test1, test2);
76+
t.pass();
77+
});

0 commit comments

Comments
 (0)