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();
+ });
+ });
+ });
+
+});