diff --git a/modules/core/data.js b/modules/core/data.js index 0a89cb0a0..e244ca216 100644 --- a/modules/core/data.js +++ b/modules/core/data.js @@ -2,46 +2,58 @@ import { json as d3_json } from 'd3-fetch'; import { data as _data } from '../../data'; // prebundled data -let _inflight = {}; - -const FILES = { - 'intro_graph': 'data/intro_graph.json' -}; - - +// +// The coreData module fetches data from JSON files +// export function coreData(context) { + let _module = {}; + let _inflight = {}; + let _fileMap = { + 'intro_graph': 'data/intro_graph.json' + }; - return { - get: (which) => { - if (_data[which]) { - return Promise.resolve(_data[which]); - } - const file = FILES[which]; - const url = file && context.asset(file); - if (!url) { - return Promise.reject(`Unknown data file for "${which}"`); - } - - let prom = _inflight[url]; - if (!prom) { - _inflight[url] = prom = d3_json(url) - .then(result => { - delete _inflight[url]; - if (!result) { - throw new Error(`No data loaded for "${which}"`); - } - _data[which] = result; - return result; - }) - .catch(err => { - delete _inflight[url]; - throw err; - }); - } - - return prom; + // Returns a Promise to fetch data + // (resolved with the data if we have it already) + _module.get = (which) => { + if (_data[which]) { + return Promise.resolve(_data[which]); } + const file = _fileMap[which]; + const url = file && context.asset(file); + if (!url) { + return Promise.reject(`Unknown data file for "${which}"`); + } + + let prom = _inflight[url]; + if (!prom) { + _inflight[url] = prom = d3_json(url) + .then(result => { + delete _inflight[url]; + if (!result) { + throw new Error(`No data loaded for "${which}"`); + } + _data[which] = result; + return result; + }) + .catch(err => { + delete _inflight[url]; + throw err; + }); + } + + return prom; }; + + + // Accessor for the file map + _module.fileMap = function(val) { + if (!arguments.length) return _fileMap; + _fileMap = val; + return _module; + }; + + + return _module; } diff --git a/test/data/intro_graph.json b/test/data/intro_graph.json new file mode 100644 index 000000000..d73b65096 --- /dev/null +++ b/test/data/intro_graph.json @@ -0,0 +1,15 @@ +{ + "n1": { + "id": "n1", + "loc": [-85.636433, 41.942959], + "tags": { + "addr:city": "Three Rivers", + "addr:housenumber": "333", + "addr:postcode": "49093", + "addr:state": "MI", + "addr:street": "Michigan Avenue", + "amenity": "townhall", + "name": "Three Rivers City Hall" + } + } +} diff --git a/test/index.html b/test/index.html index 7ea279990..6c5640719 100644 --- a/test/index.html +++ b/test/index.html @@ -71,6 +71,7 @@ + diff --git a/test/spec/core/data.js b/test/spec/core/data.js new file mode 100644 index 000000000..908b812c4 --- /dev/null +++ b/test/spec/core/data.js @@ -0,0 +1,62 @@ +describe('iD.coreData', function() { + var _context; + var _oldData; + + before(function() { + iD.data.test = { hello: 'world' }; + }); + + after(function() { + delete iD.data.test; + }); + + beforeEach(function() { + _context = iD.coreContext(); + }); + + + describe('#fileMap', function() { + it('gets the fileMap', function() { + var data = iD.coreData(_context); + expect(data.fileMap()).to.be.a('object'); + }); + it('sets the fileMap', function() { + var data = iD.coreData(_context); + var files = { 'intro_graph': 'data/intro_graph.json' }; + expect(data.fileMap(files)).to.be.ok; + }); + }); + + describe('#get', function() { + it('returns a promise resolved if we already have the data', function(done) { + var data = iD.coreData(_context); + var prom = data.get('test'); + expect(prom).to.be.a('promise'); + prom.then(function (data) { + expect(data).to.be.a('object'); + expect(data.hello).to.eql('world'); + done(); + }); + }); + it('returns a promise rejected if we can not get the data', function(done) { + var data = iD.coreData(_context); + var prom = data.get('wat'); + prom.catch(function (err) { + expect(/^Unknown data file/.test(err)).to.be.true; + done(); + }); + }); + it('returns a promise to fetch data if we do not already have the data', function(done) { + var files = { 'intro_graph': 'data/intro_graph.json' }; + var data = iD.coreData(_context).fileMap(files); + var prom = data.get('intro_graph'); + expect(prom).to.be.a('promise'); + prom.then(function (data) { + expect(data).to.be.a('object'); + expect(data.n1.tags.name).to.eql('Three Rivers City Hall'); + done(); + }); + }); + }); + +});