Simon Hunt
Committed by Gerrit Code Review

GUI -- Revamp of the Glyph Service to allow for custom viewboxes to be defined f…

…or registered glyphs/sprites.
- Also, initial sketch for externally injected sprite definition and placement.
- Added 'cloud' sprite data.

Change-Id: I1c38d50212a6d67e00e9b7c15427f6e0af40b539
...@@ -24,15 +24,13 @@ ...@@ -24,15 +24,13 @@
24 var $log, fs, sus; 24 var $log, fs, sus;
25 25
26 // internal state 26 // internal state
27 - var glyphs = d3.map(), 27 + var glyphs = d3.map();
28 - msgGS = 'GlyphService.';
29 28
30 // ---------------------------------------------------------------------- 29 // ----------------------------------------------------------------------
31 // Base set of Glyphs... 30 // Base set of Glyphs...
32 31
33 - var birdViewBox = '352 224 113 112', 32 + var birdData = {
34 - 33 + _bird: "352 224 113 112",
35 - birdData = {
36 bird: "M427.7,300.4 c-6.9,0.6-13.1,5-19.2,7.1c-18.1,6.2-33.9," + 34 bird: "M427.7,300.4 c-6.9,0.6-13.1,5-19.2,7.1c-18.1,6.2-33.9," +
37 "9.1-56.5,4.7c24.6,17.2,36.6,13,63.7,0.1c-0.5,0.6-0.7,1.3-1.3," + 35 "9.1-56.5,4.7c24.6,17.2,36.6,13,63.7,0.1c-0.5,0.6-0.7,1.3-1.3," +
38 "1.9c1.4-0.4,2.4-1.7,3.4-2.2c-0.4,0.7-0.9,1.5-1.4,1.9c2.2-0.6," + 36 "1.9c1.4-0.4,2.4-1.7,3.4-2.2c-0.4,0.7-0.9,1.5-1.4,1.9c2.2-0.6," +
...@@ -47,9 +45,9 @@ ...@@ -47,9 +45,9 @@
47 "C429.9,285.5,426.7,293.2,427.7,300.4z" 45 "C429.9,285.5,426.7,293.2,427.7,300.4z"
48 }, 46 },
49 47
50 - glyphViewBox = '0 0 110 110', 48 + glyphDataSet = {
49 + _viewbox: "0 0 110 110",
51 50
52 - glyphData = {
53 unknown: "M35,40a5,5,0,0,1,5-5h30a5,5,0,0,1,5,5v30a5,5,0,0,1-5,5" + 51 unknown: "M35,40a5,5,0,0,1,5-5h30a5,5,0,0,1,5,5v30a5,5,0,0,1-5,5" +
54 "h-30a5,5,0,0,1-5-5z", 52 "h-30a5,5,0,0,1-5-5z",
55 53
...@@ -288,9 +286,9 @@ ...@@ -288,9 +286,9 @@
288 "L22,23.7z M97.9,46.5H77.2L88,23.7L97.9,46.5z" 286 "L22,23.7z M97.9,46.5H77.2L88,23.7L97.9,46.5z"
289 }, 287 },
290 288
291 - badgeViewBox = '0 0 10 10', 289 + badgeDataSet = {
290 + _viewbox: "0 0 10 10",
292 291
293 - badgeData = {
294 uiAttached: "M2,2.5a.5,.5,0,0,1,.5-.5h5a.5,.5,0,0,1,.5,.5v3" + 292 uiAttached: "M2,2.5a.5,.5,0,0,1,.5-.5h5a.5,.5,0,0,1,.5,.5v3" +
295 "a.5,.5,0,0,1-.5,.5h-5a.5,.5,0,0,1-.5-.5zM2.5,2.8a.3,.3,0,0,1," + 293 "a.5,.5,0,0,1-.5,.5h-5a.5,.5,0,0,1-.5-.5zM2.5,2.8a.3,.3,0,0,1," +
296 ".3-.3h4.4a.3,.3,0,0,1,.3,.3v2.4a.3,.3,0,0,1-.3,.3h-4.4" + 294 ".3-.3h4.4a.3,.3,0,0,1,.3,.3v2.4a.3,.3,0,0,1-.3,.3h-4.4" +
...@@ -324,9 +322,70 @@ ...@@ -324,9 +322,70 @@
324 play: "M2.5,2l5.5,3l-5.5,3z", 322 play: "M2.5,2l5.5,3l-5.5,3z",
325 323
326 stop: "M2.5,2.5h5v5h-5z" 324 stop: "M2.5,2.5h5v5h-5z"
325 + },
326 +
327 + spriteData = {
328 + _cloud: '0 0 110 110',
329 + cloud: "M37.6,79.5c-6.9,8.7-20.4,8.6-22.2-2.7" +
330 + "M16.3,41.2c-0.8-13.9,19.4-19.2,23.5-7.8" +
331 + "M38.9,30.9c5.1-9.4,15.1-8.5,16.9-1.3" +
332 + "M54.4,32.9c4-12.9,14.8-9.6,18.6-3.8" +
333 + "M95.8,58.5c10-4.1,11.7-17.8-0.9-19.8" +
334 + "M18.1,76.4C5.6,80.3,3.8,66,13.8,61.5" +
335 + "M16.2,62.4C2.1,58.4,3.5,36,16.8,36.6" +
336 + "M93.6,74.7c10.2-2,10.7-14,5.8-18.3" +
337 + "M71.1,79.3c11.2,7.6,24.6,6.4,22.1-11.7" +
338 + "M36.4,76.8c3.4,13.3,35.4,11.6,36.1-1.4" +
339 + "M70.4,31c11.8-10.4,26.2-5.2,24.7,10.1"
327 }; 340 };
328 341
329 // ---------------------------------------------------------------------- 342 // ----------------------------------------------------------------------
343 + // === Constants
344 +
345 + var msgGS = 'GlyphService.',
346 + rg = "registerGlyphs(): ",
347 + rgs = "registerGlyphSet(): ";
348 +
349 + // ----------------------------------------------------------------------
350 +
351 + function warn(msg) {
352 + $log.warn(msgGS + msg);
353 + }
354 +
355 + function addToMap(key, value, vbox, overwrite, dups) {
356 + if (!overwrite && glyphs.get(key)) {
357 + dups.push(key);
358 + } else {
359 + glyphs.set(key, {id: key, vb: vbox, d: value});
360 + }
361 + }
362 +
363 + function reportDups(dups, which) {
364 + var ok = (dups.length == 0),
365 + msg = 'ID collision: ';
366 +
367 + if (!ok) {
368 + dups.forEach(function (id) {
369 + warn(which + msg + '"' + id + '"');
370 + });
371 + }
372 + return ok;
373 + }
374 +
375 + function reportMissVb(missing, which) {
376 + var ok = (missing.length == 0),
377 + msg = 'Missing viewbox property: ';
378 +
379 + if (!ok) {
380 + missing.forEach(function (vbk) {
381 + warn(which + msg + '"' + vbk + '"');
382 + });
383 + }
384 + return ok;
385 + }
386 +
387 + // ----------------------------------------------------------------------
388 + // === API functions ===
330 389
331 function clear() { 390 function clear() {
332 // start with a fresh map 391 // start with a fresh map
...@@ -335,30 +394,46 @@ ...@@ -335,30 +394,46 @@
335 394
336 function init() { 395 function init() {
337 clear(); 396 clear();
338 - register(birdViewBox, birdData); 397 + registerGlyphs(birdData);
339 - register(glyphViewBox, glyphData); 398 + registerGlyphSet(glyphDataSet);
340 - register(badgeViewBox, badgeData); 399 + registerGlyphSet(badgeDataSet);
400 + registerGlyphs(spriteData);
341 } 401 }
342 402
343 - function register(viewBox, data, overwrite) { 403 + function registerGlyphs(data, overwrite) {
344 - var dmap = d3.map(data), 404 + var dups = [],
345 - dups = [], 405 + missvb = [];
346 - ok;
347 406
348 - dmap.forEach(function (key, value) { 407 + angular.forEach(data, function (value, key) {
349 - if (!overwrite && glyphs.get(key)) { 408 + var vbk = '_' + key,
350 - dups.push(key); 409 + vb = data[vbk];
351 - } else { 410 +
352 - glyphs.set(key, {id: key, vb: viewBox, d: value}); 411 + if (key[0] !== '_') {
412 + if (!vb) {
413 + missvb.push(vbk);
414 + return;
415 + }
416 + addToMap(key, value, vb, overwrite, dups);
353 } 417 }
354 }); 418 });
355 - ok = (dups.length == 0); 419 + return reportDups(dups, rg) && reportMissVb(missvb, rg);
356 - if (!ok) { 420 + }
357 - dups.forEach(function (id) { 421 +
358 - $log.warn(msgGS + 'register(): ID collision: "'+id+'"'); 422 + function registerGlyphSet(data, overwrite) {
359 - }); 423 + var dups = [],
424 + vb = data._viewbox;
425 +
426 + if (!vb) {
427 + warn(rgs + 'no "_viewbox" property found');
428 + return false;
360 } 429 }
361 - return ok; 430 +
431 + angular.forEach(data, function (value, key) {
432 + if (key[0] !== '_') {
433 + addToMap(key, value, vb, overwrite, dups);
434 + }
435 + });
436 + return reportDups(dups, rgs);
362 } 437 }
363 438
364 function ids() { 439 function ids() {
...@@ -428,7 +503,8 @@ ...@@ -428,7 +503,8 @@
428 return { 503 return {
429 clear: clear, 504 clear: clear,
430 init: init, 505 init: init,
431 - register: register, 506 + registerGlyphs: registerGlyphs,
507 + registerGlyphSet: registerGlyphSet,
432 ids: ids, 508 ids: ids,
433 glyph: glyph, 509 glyph: glyph,
434 loadDefs: loadDefs, 510 loadDefs: loadDefs,
......
...@@ -247,6 +247,25 @@ ...@@ -247,6 +247,25 @@
247 .attr('opacity', b ? 1 : 0); 247 .attr('opacity', b ? 1 : 0);
248 } 248 }
249 249
250 + function addSprites() {
251 + var g = zoomLayer.append ('g').attr('id', 'topo-sprites');
252 +
253 + function cloud(g, x, y) {
254 + g.append('use').attr({
255 + width: 100,
256 + height: 100,
257 + 'xlink:href': '#cloud',
258 + transform: sus.translate([x, y]) + sus.scale(4,4)
259 + }).style('stroke', 'goldenrod')
260 + .style('fill', 'none')
261 + .style('stroke-width', 1.0);
262 + }
263 +
264 + cloud(g, 0, 50);
265 + cloud(g, 800, 40);
266 + cloud(g, 400, 450);
267 + }
268 +
250 // --- User Preferemces ---------------------------------------------- 269 // --- User Preferemces ----------------------------------------------
251 270
252 var prefsState = {}; 271 var prefsState = {};
...@@ -354,6 +373,7 @@ ...@@ -354,6 +373,7 @@
354 toggleMap(prefsState.bg); 373 toggleMap(prefsState.bg);
355 } 374 }
356 ); 375 );
376 + // addSprites();
357 377
358 forceG = zoomLayer.append('g').attr('id', 'topo-force'); 378 forceG = zoomLayer.append('g').attr('id', 'topo-force');
359 tfs.initForce(svg, forceG, uplink, dim); 379 tfs.initForce(svg, forceG, uplink, dim);
......
1 +{
2 + "_comment": [
3 + "configuration file for loading canned and/or custom sprites (and labels)",
4 + "into the topology view. These appear above the map layer, but below",
5 + "the nodes/links layer."
6 + ],
7 +
8 + "_comment_defn": "'defn' array contains custom sprite definitions",
9 + "defn": [
10 +
11 + ],
12 +
13 + "_comment_defstyle": "'defstyle' defines default styles to apply",
14 + "defstyle": {
15 + "sprite": {
16 + "stroke": "goldenrod",
17 + "stroke-width": 1.0,
18 + "fill": "none"
19 + },
20 + "text": {
21 + "text-style": "italic",
22 + "test-size": "20pt"
23 + }
24 + },
25 +
26 + "_comment_load": [
27 + "'load' array contains list of sprites/labels to load",
28 + " note that 'copies' array defines [x,y] coords to position copies"
29 + ],
30 + "load": [
31 + {
32 + "id": "cloud",
33 + "width": 100,
34 + "height": 100,
35 + "scale": 4.0,
36 + "copies": [
37 + [0, 50], [800, 40], [400, 450]
38 + ],
39 + "style": {
40 + "stroke": "green"
41 + }
42 + }
43 + ]
44 +}
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 describe('factory: fw/svg/glyph.js', function() { 20 describe('factory: fw/svg/glyph.js', function() {
21 var $log, fs, gs, d3Elem, svg; 21 var $log, fs, gs, d3Elem, svg;
22 22
23 - var numBaseGlyphs = 35, 23 + var numBaseGlyphs = 36,
24 vbBird = '352 224 113 112', 24 vbBird = '352 224 113 112',
25 vbGlyph = '0 0 110 110', 25 vbGlyph = '0 0 110 110',
26 vbBadge = '0 0 10 10', 26 vbBadge = '0 0 10 10',
...@@ -67,6 +67,8 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -67,6 +67,8 @@ describe('factory: fw/svg/glyph.js', function() {
67 play: 'M2.5,2l5.5,3', 67 play: 'M2.5,2l5.5,3',
68 stop: 'M2.5,2.5h5', 68 stop: 'M2.5,2.5h5',
69 69
70 + cloud: 'M37.6,79.5c-6.9,8.7-20.4,8.6',
71 +
70 // our test ones.. 72 // our test ones..
71 triangle: 'M.5,.2', 73 triangle: 'M.5,.2',
72 diamond: 'M.2,.5' 74 diamond: 'M.2,.5'
...@@ -81,6 +83,9 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -81,6 +83,9 @@ describe('factory: fw/svg/glyph.js', function() {
81 badgeIds = [ 83 badgeIds = [
82 'uiAttached', 'checkMark', 'xMark', 'triangleUp', 'triangleDown', 84 'uiAttached', 'checkMark', 'xMark', 'triangleUp', 'triangleDown',
83 'plus', 'minus', 'play', 'stop' 85 'plus', 'minus', 'play', 'stop'
86 + ],
87 + spriteIds = [
88 + 'cloud'
84 ]; 89 ];
85 90
86 beforeEach(module('onosUtil', 'onosSvg')); 91 beforeEach(module('onosUtil', 'onosSvg'));
...@@ -106,8 +111,9 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -106,8 +111,9 @@ describe('factory: fw/svg/glyph.js', function() {
106 111
107 it('should define api functions', function () { 112 it('should define api functions', function () {
108 expect(fs.areFunctions(gs, [ 113 expect(fs.areFunctions(gs, [
109 - 'clear', 'init', 'register', 'ids', 'glyph', 'loadDefs', 'addGlyph' 114 + 'clear', 'init', 'registerGlyphs', 'registerGlyphSet',
110 - ])).toBeTruthy(); 115 + 'ids', 'glyph', 'loadDefs', 'addGlyph'
116 + ])).toBe(true);
111 }); 117 });
112 118
113 it('should start with no glyphs loaded', function () { 119 it('should start with no glyphs loaded', function () {
...@@ -131,7 +137,7 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -131,7 +137,7 @@ describe('factory: fw/svg/glyph.js', function() {
131 glyph = gs.glyph(id), 137 glyph = gs.glyph(id),
132 prefix = prefixLookup[pfxId], 138 prefix = prefixLookup[pfxId],
133 plen = prefix.length; 139 plen = prefix.length;
134 - expect(fs.contains(gs.ids(), id)).toBeTruthy(); 140 + expect(fs.contains(gs.ids(), id)).toBe(true);
135 expect(glyph).toBeDefined(); 141 expect(glyph).toBeDefined();
136 expect(glyph.id).toEqual(id); 142 expect(glyph.id).toEqual(id);
137 expect(glyph.vb).toEqual(vbox); 143 expect(glyph.vb).toEqual(vbox);
...@@ -139,7 +145,8 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -139,7 +145,8 @@ describe('factory: fw/svg/glyph.js', function() {
139 } 145 }
140 146
141 it('should be configured with the correct number of glyphs', function () { 147 it('should be configured with the correct number of glyphs', function () {
142 - expect(1 + glyphIds.length + badgeIds.length).toEqual(numBaseGlyphs); 148 + var nGlyphs = 1 + glyphIds.length + badgeIds.length + spriteIds.length;
149 + expect(nGlyphs).toEqual(numBaseGlyphs);
143 }); 150 });
144 151
145 it('should load the bird glyph', function() { 152 it('should load the bird glyph', function() {
...@@ -161,29 +168,64 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -161,29 +168,64 @@ describe('factory: fw/svg/glyph.js', function() {
161 }); 168 });
162 }); 169 });
163 170
171 + it('should load the sprites', function () {
172 + gs.init();
173 + spriteIds.forEach(function (id) {
174 + verifyGlyphLoadedInCache(id, vbGlyph);
175 + });
176 + });
177 +
164 178
165 // define some glyphs that we want to install 179 // define some glyphs that we want to install
166 180
167 var testVbox = '0 0 1 1', 181 var testVbox = '0 0 1 1',
182 + triVbox = '0 0 12 12',
183 + diaVbox = '0 0 15 15',
168 dTriangle = 'M.5,.2l.3,.6,h-.6z', 184 dTriangle = 'M.5,.2l.3,.6,h-.6z',
169 dDiamond = 'M.2,.5l.3,-.3l.3,.3l-.3,.3z', 185 dDiamond = 'M.2,.5l.3,-.3l.3,.3l-.3,.3z',
170 newGlyphs = { 186 newGlyphs = {
187 + _viewbox: testVbox,
171 triangle: dTriangle, 188 triangle: dTriangle,
172 diamond: dDiamond 189 diamond: dDiamond
173 }, 190 },
174 dupGlyphs = { 191 dupGlyphs = {
192 + _viewbox: testVbox,
175 router: dTriangle, 193 router: dTriangle,
176 switch: dDiamond 194 switch: dDiamond
177 }, 195 },
178 - idCollision = 'GlyphService.register(): ID collision: '; 196 + altNewGlyphs = {
197 + _triangle: triVbox,
198 + triangle: dTriangle,
199 + _diamond: diaVbox,
200 + diamond: dDiamond
201 + },
202 + altDupGlyphs = {
203 + _router: triVbox,
204 + router: dTriangle,
205 + _switch: diaVbox,
206 + switch: dDiamond
207 + },
208 + badGlyphSet = {
209 + triangle: dTriangle,
210 + diamond: dDiamond
211 + },
212 + warnMsg = 'GlyphService.registerGlyphs(): ',
213 + warnMsgSet = 'GlyphService.registerGlyphSet(): ',
214 + idCollision = warnMsg + 'ID collision: ',
215 + idCollisionSet = warnMsgSet + 'ID collision: ',
216 + missVbSet = warnMsgSet + 'no "_viewbox" property found',
217 + missVbCustom = warnMsg + 'Missing viewbox property: ',
218 + missVbTri = missVbCustom + '"_triangle"',
219 + missVbDia = missVbCustom + '"_diamond"';
179 220
180 - it('should install new glyphs', function () { 221 +
222 + it('should install new glyphs as a glyph-set', function () {
181 gs.init(); 223 gs.init();
182 expect(gs.ids().length).toEqual(numBaseGlyphs); 224 expect(gs.ids().length).toEqual(numBaseGlyphs);
183 spyOn($log, 'warn'); 225 spyOn($log, 'warn');
184 226
185 - var ok = gs.register(testVbox, newGlyphs); 227 + var ok = gs.registerGlyphSet(newGlyphs);
186 - expect(ok).toBeTruthy(); 228 + expect(ok).toBe(true);
187 expect($log.warn).not.toHaveBeenCalled(); 229 expect($log.warn).not.toHaveBeenCalled();
188 230
189 expect(gs.ids().length).toEqual(numBaseGlyphs + 2); 231 expect(gs.ids().length).toEqual(numBaseGlyphs + 2);
...@@ -191,13 +233,69 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -191,13 +233,69 @@ describe('factory: fw/svg/glyph.js', function() {
191 verifyGlyphLoadedInCache('diamond', testVbox); 233 verifyGlyphLoadedInCache('diamond', testVbox);
192 }); 234 });
193 235
236 + it('should not overwrite glyphs (via glyph-set) with dup IDs', function () {
237 + gs.init();
238 + expect(gs.ids().length).toEqual(numBaseGlyphs);
239 + spyOn($log, 'warn');
240 +
241 + var ok = gs.registerGlyphSet(dupGlyphs);
242 + expect(ok).toBe(false);
243 + expect($log.warn).toHaveBeenCalledWith(idCollisionSet + '"switch"');
244 + expect($log.warn).toHaveBeenCalledWith(idCollisionSet + '"router"');
245 +
246 + expect(gs.ids().length).toEqual(numBaseGlyphs);
247 + // verify original glyphs still exist...
248 + verifyGlyphLoadedInCache('router', vbGlyph);
249 + verifyGlyphLoadedInCache('switch', vbGlyph);
250 + });
251 +
252 + it('should replace glyphs (via glyph-set) if asked nicely', function () {
253 + gs.init();
254 + expect(gs.ids().length).toEqual(numBaseGlyphs);
255 + spyOn($log, 'warn');
256 +
257 + var ok = gs.registerGlyphSet(dupGlyphs, true);
258 + expect(ok).toBe(true);
259 + expect($log.warn).not.toHaveBeenCalled();
260 +
261 + expect(gs.ids().length).toEqual(numBaseGlyphs);
262 + // verify glyphs have been overwritten...
263 + verifyGlyphLoadedInCache('router', testVbox, 'triangle');
264 + verifyGlyphLoadedInCache('switch', testVbox, 'diamond');
265 + });
266 +
267 + it ('should complain if missing _viewbox in a glyph-set', function () {
268 + gs.init();
269 + expect(gs.ids().length).toEqual(numBaseGlyphs);
270 + spyOn($log, 'warn');
271 +
272 + var ok = gs.registerGlyphSet(badGlyphSet);
273 + expect(ok).toBe(false);
274 + expect($log.warn).toHaveBeenCalledWith(missVbSet);
275 + expect(gs.ids().length).toEqual(numBaseGlyphs);
276 + });
277 +
278 + it('should install new glyphs', function () {
279 + gs.init();
280 + expect(gs.ids().length).toEqual(numBaseGlyphs);
281 + spyOn($log, 'warn');
282 +
283 + var ok = gs.registerGlyphs(altNewGlyphs);
284 + expect(ok).toBe(true);
285 + expect($log.warn).not.toHaveBeenCalled();
286 +
287 + expect(gs.ids().length).toEqual(numBaseGlyphs + 2);
288 + verifyGlyphLoadedInCache('triangle', triVbox);
289 + verifyGlyphLoadedInCache('diamond', diaVbox);
290 + });
291 +
194 it('should not overwrite glyphs with dup IDs', function () { 292 it('should not overwrite glyphs with dup IDs', function () {
195 gs.init(); 293 gs.init();
196 expect(gs.ids().length).toEqual(numBaseGlyphs); 294 expect(gs.ids().length).toEqual(numBaseGlyphs);
197 spyOn($log, 'warn'); 295 spyOn($log, 'warn');
198 296
199 - var ok = gs.register(testVbox, dupGlyphs); 297 + var ok = gs.registerGlyphs(altDupGlyphs);
200 - expect(ok).toBeFalsy(); 298 + expect(ok).toBe(false);
201 expect($log.warn).toHaveBeenCalledWith(idCollision + '"switch"'); 299 expect($log.warn).toHaveBeenCalledWith(idCollision + '"switch"');
202 expect($log.warn).toHaveBeenCalledWith(idCollision + '"router"'); 300 expect($log.warn).toHaveBeenCalledWith(idCollision + '"router"');
203 301
...@@ -212,14 +310,26 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -212,14 +310,26 @@ describe('factory: fw/svg/glyph.js', function() {
212 expect(gs.ids().length).toEqual(numBaseGlyphs); 310 expect(gs.ids().length).toEqual(numBaseGlyphs);
213 spyOn($log, 'warn'); 311 spyOn($log, 'warn');
214 312
215 - var ok = gs.register(testVbox, dupGlyphs, true); 313 + var ok = gs.registerGlyphs(altDupGlyphs, true);
216 - expect(ok).toBeTruthy(); 314 + expect(ok).toBe(true);
217 expect($log.warn).not.toHaveBeenCalled(); 315 expect($log.warn).not.toHaveBeenCalled();
218 316
219 expect(gs.ids().length).toEqual(numBaseGlyphs); 317 expect(gs.ids().length).toEqual(numBaseGlyphs);
220 // verify glyphs have been overwritten... 318 // verify glyphs have been overwritten...
221 - verifyGlyphLoadedInCache('router', testVbox, 'triangle'); 319 + verifyGlyphLoadedInCache('router', triVbox, 'triangle');
222 - verifyGlyphLoadedInCache('switch', testVbox, 'diamond'); 320 + verifyGlyphLoadedInCache('switch', diaVbox, 'diamond');
321 + });
322 +
323 + it ('should complain if missing custom viewbox', function () {
324 + gs.init();
325 + expect(gs.ids().length).toEqual(numBaseGlyphs);
326 + spyOn($log, 'warn');
327 +
328 + var ok = gs.registerGlyphs(badGlyphSet);
329 + expect(ok).toBe(false);
330 + expect($log.warn).toHaveBeenCalledWith(missVbTri);
331 + expect($log.warn).toHaveBeenCalledWith(missVbDia);
332 + expect(gs.ids().length).toEqual(numBaseGlyphs);
223 }); 333 });
224 334
225 function verifyPathPrefix(elem, prefix) { 335 function verifyPathPrefix(elem, prefix) {
...@@ -245,7 +355,7 @@ describe('factory: fw/svg/glyph.js', function() { ...@@ -245,7 +355,7 @@ describe('factory: fw/svg/glyph.js', function() {
245 355
246 it('should load custom glyphs into the DOM', function () { 356 it('should load custom glyphs into the DOM', function () {
247 gs.init(); 357 gs.init();
248 - gs.register(testVbox, newGlyphs); 358 + gs.registerGlyphSet(newGlyphs);
249 gs.loadDefs(d3Elem); 359 gs.loadDefs(d3Elem);
250 expect(d3Elem.selectAll('symbol').size()).toEqual(numBaseGlyphs + 2); 360 expect(d3Elem.selectAll('symbol').size()).toEqual(numBaseGlyphs + 2);
251 verifyLoadedInDom('diamond', testVbox); 361 verifyLoadedInDom('diamond', testVbox);
......