Simon Hunt

GUI -- Sketched out MapService.

- implemented ID to URL adjustment, and object caching behaviors.

Change-Id: I5a30b59be01761d9a6475f7707db947dd2304dc5
...@@ -19,17 +19,81 @@ ...@@ -19,17 +19,81 @@
19 19
20 @author Simon Hunt 20 @author Simon Hunt
21 */ 21 */
22 +
23 +/*
24 + The Map Service caches GeoJSON maps, which can be loaded into the map
25 + layer of the Topology View.
26 +
27 + A GeoMap object can be fetched by ID. IDs that start with an asterisk
28 + identify maps bundled with the GUI. IDs that do not start with an
29 + asterisk are assumed to be URLs to externally provided data (exact
30 + format to be decided).
31 +
32 + e.g. var geomap = MapService.fetchGeoMap('*continental-us');
33 +
34 + The GeoMap object encapsulates topology data (features), and the
35 + D3 projection object.
36 +
37 + Note that, since the GeoMap instance is cached / shared, it should
38 + contain no state.
39 + */
40 +
22 (function () { 41 (function () {
23 'use strict'; 42 'use strict';
24 43
25 - var $log; 44 + // injected references
45 + var $log, fs;
46 +
47 + // internal state
48 + var maps = d3.map(),
49 + msgMs = 'MapService.',
50 + bundledUrlPrefix = 'data/map/';
51 +
52 + function getUrl(id) {
53 + if (id[0] === '*') {
54 + return bundledUrlPrefix + id.slice(1) + '.json';
55 + }
56 + return id + '.json';
57 + }
26 58
27 angular.module('onosSvg') 59 angular.module('onosSvg')
28 - .factory('MapService', ['$log', function (_$log_) { 60 + .factory('MapService', ['$log', 'FnService',
61 +
62 + function (_$log_, _fs_) {
29 $log = _$log_; 63 $log = _$log_;
64 + fs = _fs_;
65 +
66 + function clearCache() {
67 + maps = d3.map();
68 + }
69 +
70 + function fetchGeoMap(id) {
71 + if (!fs.isS(id)) {
72 + return null;
73 + }
74 +
75 + var geomap = maps.get(id);
76 +
77 + if (!geomap) {
78 + // need to fetch the data and build the object...
79 + geomap = {
80 + id: id,
81 + url: getUrl(id),
82 + wasCached: false
83 + };
84 + // TODO: use $http service to load map data asynchronously
85 +
86 + maps.set(id, geomap);
87 + } else {
88 + geomap.wasCached = true;
89 + }
90 +
91 + return geomap;
92 + }
30 93
31 return { 94 return {
32 - tbd: function () {} 95 + clearCache: clearCache,
96 + fetchGeoMap: fetchGeoMap
33 }; 97 };
34 }]); 98 }]);
35 99
......
...@@ -22,6 +22,6 @@ ...@@ -22,6 +22,6 @@
22 (function () { 22 (function () {
23 'use strict'; 23 'use strict';
24 24
25 - angular.module('onosSvg', []); 25 + angular.module('onosSvg', ['onosUtil']);
26 26
27 }()); 27 }());
......
...@@ -20,17 +20,80 @@ ...@@ -20,17 +20,80 @@
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 ms; 23 + var $log, fs, ms, d3Elem, geomap;
24 24
25 - beforeEach(module('onosSvg')); 25 + var urlPrefix = 'data/map/';
26 26
27 - beforeEach(inject(function (MapService) { 27 + beforeEach(module('onosUtil', 'onosSvg'));
28 +
29 + beforeEach(inject(function (_$log_, FnService, MapService) {
30 + $log = _$log_;
31 + fs = FnService;
28 ms = MapService; 32 ms = MapService;
33 + ms.clearCache();
34 + // TODO: d3Elem = d3.select('body').append('...').attr('id', 'myFoo');
29 })); 35 }));
30 36
37 + afterEach(function () {
38 + // TODO d3.select('#myFoo').remove();
39 + });
40 +
31 it('should define MapService', function () { 41 it('should define MapService', function () {
32 expect(ms).toBeDefined(); 42 expect(ms).toBeDefined();
33 }); 43 });
34 44
35 - // TODO: unit tests for map functions 45 + it('should define api functions', function () {
46 + expect(fs.areFunctions(ms, [
47 + 'clearCache', 'fetchGeoMap'
48 + ])).toBeTruthy();
49 + });
50 +
51 + it('should return null when no parameters given', function () {
52 + geomap = ms.fetchGeoMap();
53 + expect(geomap).toBeNull();
54 + });
55 +
56 + it('should augment the id of a bundled map', function () {
57 + var id = '*foo';
58 + geomap = ms.fetchGeoMap(id);
59 + expect(geomap).toBeDefined();
60 + expect(geomap.id).toBe(id);
61 + expect(geomap.url).toBe('data/map/foo.json');
62 + });
63 +
64 + it('should treat an external id as the url itself', function () {
65 + var id = 'some/path/to/foo';
66 + geomap = ms.fetchGeoMap(id);
67 + expect(geomap).toBeDefined();
68 + expect(geomap.id).toBe(id);
69 + expect(geomap.url).toBe(id + '.json');
70 + });
71 +
72 + it('should cache the returned objects', function () {
73 + var id = 'foo';
74 + geomap = ms.fetchGeoMap(id);
75 + expect(geomap).toBeDefined();
76 + expect(geomap.wasCached).toBeFalsy();
77 + expect(geomap.tagged).toBeUndefined();
78 +
79 + geomap.tagged = 'I woz here';
80 +
81 + geomap = ms.fetchGeoMap(id);
82 + expect(geomap).toBeDefined();
83 + expect(geomap.wasCached).toBeTruthy();
84 + expect(geomap.tagged).toEqual('I woz here');
85 + });
86 +
87 + it('should clear the cache when asked', function () {
88 + var id = 'foo';
89 + geomap = ms.fetchGeoMap(id);
90 + expect(geomap.wasCached).toBeFalsy();
91 +
92 + geomap = ms.fetchGeoMap(id);
93 + expect(geomap.wasCached).toBeTruthy();
94 +
95 + ms.clearCache();
96 + geomap = ms.fetchGeoMap(id);
97 + expect(geomap.wasCached).toBeFalsy();
98 + });
36 }); 99 });
......