diff --git a/.travis.yml b/.travis.yml index a8ed3a8..54edb70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ cache: - node_modules install: - npm install + - node build.sh script: - jest --silent --coverage --coverageReporters=text-lcov | coveralls - jshint ./src \ No newline at end of file diff --git a/build.js b/build.js index ca7cb3c..653919d 100644 --- a/build.js +++ b/build.js @@ -86,7 +86,7 @@ svn.commands.checkout(FA_SVG_FOLDER_URL, svgDir, (err) => { svgs[type][name] = { path: match2[1], - width: match1[1] + width: parseInt(match1[1]) }; count++; diff --git a/src/rendering.js b/src/rendering.js index fcc7acc..39a1be1 100644 --- a/src/rendering.js +++ b/src/rendering.js @@ -7,6 +7,14 @@ try { console.error('fa-diagrams: SVG list could not be loaded', err); } +/** + * @typedef Node2 + * @property {string} name + * @property {number} x + * @property {number} y + * @property {string} icon + */ + const DEFAULT_OPTIONS = { 'beautify': false }; @@ -15,6 +23,56 @@ module.exports = (options = DEFAULT_OPTIONS) => { const self = { defaultOptions: DEFAULT_OPTIONS, + /** + * Find icon data from given name + * @param {string} name + * @returns {null|{path: string, width: number}} + */ + getIcon: (name) => { + if (!name || !name.trim()) + return null; + + let search = ['solid', 'regular', 'brands']; + const spl = name.trim().split(' ').map(t => t.indexOf('fa-') === 0 ? t.substr(3) : t); + + const checkType = (type, keywords) => { + if (search.length > 1) // else it's already found + keywords.forEach(kw => { + const i = spl.indexOf(kw); + if (i >= 0) { + spl.splice(i, 1); + search = [type]; + } + }); + }; + + checkType('solid', ['fas', 'solid']); + checkType('regular', ['far', 'regular']); + checkType('brands', ['fab', 'brands']); + + name = spl[0]; + + for (let i = 0; i < search.length; i++) { + if (list[search[i]] && list[search[i]][name]) { + return list[search[i]][name]; + } + } + + return null; + }, + + /** + * @param {Object} nodes + * @returns {Object} + */ + renderNodes: (nodes) => { + const g = []; + Object.values(nodes).forEach(() => { + //TODO + }); + return {'g': g}; + }, + /** * Convert xml-js data into correct svg xml string * @param {Object} data @@ -40,8 +98,9 @@ module.exports = (options = DEFAULT_OPTIONS) => { }); }, - compute: () => { - return self.toXML({}, 0, 0); //TODO temporary + compute: (nodes) => { + const data = self.renderNodes(nodes); + return self.toXML(data, 0, 0); //TODO temporary } }; diff --git a/test/rendering.test.js b/test/rendering.test.js index 663a1a9..6c0cd6d 100644 --- a/test/rendering.test.js +++ b/test/rendering.test.js @@ -1,6 +1,87 @@ /* jshint -W117 */ const rendering = require('../src/rendering'); +describe('getIcon', () => { + const solidCirclePath = 'M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z'; + const regularCirclePath = 'M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z'; + + test('no name', () => { + const res = rendering().getIcon(undefined); + expect(res).toBeNull(); + }); + test('empty name', () => { + const res = rendering().getIcon(' '); + expect(res).toBeNull(); + }); + test('invalid name', () => { + const res = rendering().getIcon('circle-2'); + expect(res).toBeNull(); + }); + test('valid circle', () => { + const res = rendering().getIcon('circle'); + expect(res).toEqual({ + path: solidCirclePath, + width: 512 + }); + }); + test('valid circle alt name', () => { + const res = rendering().getIcon('fa-circle'); + expect(res).toEqual({ + path: solidCirclePath, + width: 512 + }); + }); + test('ignored other name', () => { + const res = rendering().getIcon('circle server'); + expect(res).toEqual({ + path: solidCirclePath, + width: 512 + }); + }); + test('forcing regular', () => { + const res = rendering().getIcon('far circle'); + expect(res).toEqual({ + path: regularCirclePath, + width: 512 + }); + }); + test('forcing regular 2', () => { + const res = rendering().getIcon('regular circle'); + expect(res).toEqual({ + path: regularCirclePath, + width: 512 + }); + }); + test('forcing regular 3', () => { + const res = rendering().getIcon('circle far'); + expect(res).toEqual({ + path: regularCirclePath, + width: 512 + }); + }); + test('double type', () => { + const res = rendering().getIcon('circle far solid'); + expect(res).toEqual({ + path: solidCirclePath, + width: 512 + }); + }); + test('double type 2', () => { + const res = rendering().getIcon('circle solid far'); + expect(res).toEqual({ + path: solidCirclePath, + width: 512 + }); + }); + test('forcing solid on brands icon', () => { + const res = rendering().getIcon('usb'); + expect(res).not.toBeNull(); + const res2 = rendering().getIcon('fas usb'); + expect(res2).toBeNull(); + }); +}); + + describe('toXML', () => { test('no data', () => { const res = rendering({beautify: false}).toXML({}, 0, 0);