Simon Hunt

GUI -- MapService: changed to cache promises with attached meta data.

- unit tests for cached promises still WIP.

Change-Id: Ibe52cf3e83ed5753ccc12581b52fa1f640354e60
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
139 function register(viewBox, data, overwrite) { 139 function register(viewBox, data, overwrite) {
140 var dmap = d3.map(data), 140 var dmap = d3.map(data),
141 dups = [], 141 dups = [],
142 - ok, msg; 142 + ok;
143 143
144 dmap.forEach(function (key, value) { 144 dmap.forEach(function (key, value) {
145 if (!overwrite && glyphs.get(key)) { 145 if (!overwrite && glyphs.get(key)) {
......
...@@ -42,12 +42,12 @@ ...@@ -42,12 +42,12 @@
42 'use strict'; 42 'use strict';
43 43
44 // injected references 44 // injected references
45 - var $log, fs; 45 + var $log, $http, $q, fs;
46 46
47 // internal state 47 // internal state
48 var maps = d3.map(), 48 var maps = d3.map(),
49 msgMs = 'MapService.', 49 msgMs = 'MapService.',
50 - bundledUrlPrefix = 'data/map/'; 50 + bundledUrlPrefix = '../data/map/';
51 51
52 function getUrl(id) { 52 function getUrl(id) {
53 if (id[0] === '*') { 53 if (id[0] === '*') {
...@@ -57,38 +57,61 @@ ...@@ -57,38 +57,61 @@
57 } 57 }
58 58
59 angular.module('onosSvg') 59 angular.module('onosSvg')
60 - .factory('MapService', ['$log', 'FnService', 60 + .factory('MapService', ['$log', '$http', '$q', 'FnService',
61 61
62 - function (_$log_, _fs_) { 62 + function (_$log_, _$http_, _$q_, _fs_) {
63 $log = _$log_; 63 $log = _$log_;
64 + $http = _$http_;
65 + $q = _$q_;
64 fs = _fs_; 66 fs = _fs_;
65 67
66 function clearCache() { 68 function clearCache() {
67 maps = d3.map(); 69 maps = d3.map();
68 } 70 }
69 71
72 + // NOTE: It is expected that mapLayer is a D3 selection of the
73 + // <g> element (a child of zoomLayer) into which the map
74 + // path data will be rendered.
75 + function renderMap(mapLayer) {
76 + // TODO ---
77 + $log.log('Hey, let\'s render the map...');
78 + }
79 +
70 function fetchGeoMap(id) { 80 function fetchGeoMap(id) {
71 if (!fs.isS(id)) { 81 if (!fs.isS(id)) {
72 return null; 82 return null;
73 } 83 }
84 + var url = getUrl(id);
74 85
75 - var geomap = maps.get(id); 86 + var promise = maps.get(id);
76 87
77 - if (!geomap) { 88 + if (!promise) {
78 // need to fetch the data and build the object... 89 // need to fetch the data and build the object...
79 - geomap = { 90 + var deferred = $q.defer();
91 + promise = deferred.promise;
92 +
93 + $http.get(url)
94 + .success(function (data) {
95 + deferred.resolve(data);
96 + })
97 + .error(function (msg, code) {
98 + deferred.reject(msg);
99 + $log.warn(msg, code);
100 + });
101 +
102 + promise.meta = {
80 id: id, 103 id: id,
81 - url: getUrl(id), 104 + url: url,
82 - wasCached: false 105 + wasCached: false,
106 + render: renderMap
83 }; 107 };
84 - // TODO: use $http service to load map data asynchronously
85 108
86 - maps.set(id, geomap); 109 + maps.set(id, promise);
87 } else { 110 } else {
88 - geomap.wasCached = true; 111 + promise.meta.wasCached = true;
89 } 112 }
90 113
91 - return geomap; 114 + return promise;
92 } 115 }
93 116
94 return { 117 return {
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
29 ]; 29 ];
30 30
31 // references to injected services etc. 31 // references to injected services etc.
32 - var $log, ks, zs, gs; 32 + var $log, ks, zs, gs, ms;
33 33
34 // DOM elements 34 // DOM elements
35 var svg, defs; 35 var svg, defs;
...@@ -106,14 +106,15 @@ ...@@ -106,14 +106,15 @@
106 angular.module('ovTopo', moduleDependencies) 106 angular.module('ovTopo', moduleDependencies)
107 107
108 .controller('OvTopoCtrl', [ 108 .controller('OvTopoCtrl', [
109 - '$log', 'KeyService', 'ZoomService', 'GlyphService', 109 + '$log', 'KeyService', 'ZoomService', 'GlyphService', 'MapService',
110 110
111 - function (_$log_, _ks_, _zs_, _gs_) { 111 + function (_$log_, _ks_, _zs_, _gs_, _ms_) {
112 var self = this; 112 var self = this;
113 $log = _$log_; 113 $log = _$log_;
114 ks = _ks_; 114 ks = _ks_;
115 zs = _zs_; 115 zs = _zs_;
116 gs = _gs_; 116 gs = _gs_;
117 + ms = _ms_;
117 118
118 // exported state 119 // exported state
119 self.message = 'Topo View Rocks!'; 120 self.message = 'Topo View Rocks!';
......
...@@ -20,9 +20,7 @@ ...@@ -20,9 +20,7 @@
20 @author Simon Hunt 20 @author Simon Hunt
21 */ 21 */
22 describe('factory: fw/svg/map.js', function() { 22 describe('factory: fw/svg/map.js', function() {
23 - var $log, fs, ms, d3Elem, geomap; 23 + var $log, fs, ms, d3Elem, promise;
24 -
25 - var urlPrefix = 'data/map/';
26 24
27 beforeEach(module('onosUtil', 'onosSvg')); 25 beforeEach(module('onosUtil', 'onosSvg'));
28 26
...@@ -49,51 +47,61 @@ describe('factory: fw/svg/map.js', function() { ...@@ -49,51 +47,61 @@ describe('factory: fw/svg/map.js', function() {
49 }); 47 });
50 48
51 it('should return null when no parameters given', function () { 49 it('should return null when no parameters given', function () {
52 - geomap = ms.fetchGeoMap(); 50 + promise = ms.fetchGeoMap();
53 - expect(geomap).toBeNull(); 51 + expect(promise).toBeNull();
54 }); 52 });
55 53
56 it('should augment the id of a bundled map', function () { 54 it('should augment the id of a bundled map', function () {
57 var id = '*foo'; 55 var id = '*foo';
58 - geomap = ms.fetchGeoMap(id); 56 + promise = ms.fetchGeoMap(id);
59 - expect(geomap).toBeDefined(); 57 + expect(promise.meta).toBeDefined();
60 - expect(geomap.id).toBe(id); 58 + expect(promise.meta.id).toBe(id);
61 - expect(geomap.url).toBe('data/map/foo.json'); 59 + expect(promise.meta.url).toBe('../data/map/foo.json');
62 }); 60 });
63 61
64 it('should treat an external id as the url itself', function () { 62 it('should treat an external id as the url itself', function () {
65 var id = 'some/path/to/foo'; 63 var id = 'some/path/to/foo';
66 - geomap = ms.fetchGeoMap(id); 64 + promise = ms.fetchGeoMap(id);
67 - expect(geomap).toBeDefined(); 65 + expect(promise.meta).toBeDefined();
68 - expect(geomap.id).toBe(id); 66 + expect(promise.meta.id).toBe(id);
69 - expect(geomap.url).toBe(id + '.json'); 67 + expect(promise.meta.url).toBe(id + '.json');
70 }); 68 });
71 69
72 it('should cache the returned objects', function () { 70 it('should cache the returned objects', function () {
73 var id = 'foo'; 71 var id = 'foo';
74 - geomap = ms.fetchGeoMap(id); 72 + promise = ms.fetchGeoMap(id);
75 - expect(geomap).toBeDefined(); 73 + expect(promise).toBeDefined();
76 - expect(geomap.wasCached).toBeFalsy(); 74 + expect(promise.meta.wasCached).toBeFalsy();
77 - expect(geomap.tagged).toBeUndefined(); 75 + expect(promise.tagged).toBeUndefined();
78 76
79 - geomap.tagged = 'I woz here'; 77 + promise.tagged = 'I woz here';
80 78
81 - geomap = ms.fetchGeoMap(id); 79 + promise = ms.fetchGeoMap(id);
82 - expect(geomap).toBeDefined(); 80 + expect(promise).toBeDefined();
83 - expect(geomap.wasCached).toBeTruthy(); 81 + expect(promise.meta.wasCached).toBeTruthy();
84 - expect(geomap.tagged).toEqual('I woz here'); 82 + expect(promise.tagged).toEqual('I woz here');
85 }); 83 });
86 84
87 it('should clear the cache when asked', function () { 85 it('should clear the cache when asked', function () {
88 var id = 'foo'; 86 var id = 'foo';
89 - geomap = ms.fetchGeoMap(id); 87 + promise = ms.fetchGeoMap(id);
90 - expect(geomap.wasCached).toBeFalsy(); 88 + expect(promise.meta.wasCached).toBeFalsy();
91 89
92 - geomap = ms.fetchGeoMap(id); 90 + promise = ms.fetchGeoMap(id);
93 - expect(geomap.wasCached).toBeTruthy(); 91 + expect(promise.meta.wasCached).toBeTruthy();
94 92
95 ms.clearCache(); 93 ms.clearCache();
96 - geomap = ms.fetchGeoMap(id); 94 + promise = ms.fetchGeoMap(id);
97 - expect(geomap.wasCached).toBeFalsy(); 95 + expect(promise.meta.wasCached).toBeFalsy();
96 + });
97 +
98 + it('should load USA into cache', function () {
99 + var id = '*continental_us';
100 + promise = ms.fetchGeoMap(id);
101 + expect(promise).toBeDefined();
102 + expect(promise.meta.id).toBe(id);
103 + expect(promise.meta.url).toBe('../data/map/continental_us.json');
104 + // TODO: WIP -- after a pause, the data should be there!!!
105 +
98 }); 106 });
99 }); 107 });
......