diff --git a/leaflet-osm.js b/leaflet-osm.js index 840b1a4..53d18bf 100644 --- a/leaflet-osm.js +++ b/leaflet-osm.js @@ -141,11 +141,14 @@ L.OSM.DataLayer = L.FeatureGroup.extend({ } }, - buildFeatures: function (xml) { - var features = L.OSM.getChangesets(xml), - nodes = L.OSM.getNodes(xml), - ways = L.OSM.getWays(xml, nodes), - relations = L.OSM.getRelations(xml, nodes, ways); + buildFeatures: function (data) { + + const parser = data instanceof Document ? L.OSM.XMLParser : L.OSM.JSONParser; + + var features = parser.getChangesets(data), + nodes = parser.getNodes(data), + ways = parser.getWays(data, nodes), + relations = parser.getRelations(data, nodes, ways); var wayNodes = {} for (var i = 0; i < ways.length; i++) { @@ -228,7 +231,7 @@ L.OSM.DataLayer = L.FeatureGroup.extend({ }, }); -L.Util.extend(L.OSM, { +L.OSM.XMLParser = { getChangesets: function (xml) { var result = []; @@ -328,4 +331,64 @@ L.Util.extend(L.OSM, { return result; } -}); +} + +L.OSM.JSONParser = { + getChangesets(json) { + const changesets = json.changeset ? [json.changeset] : []; + + return changesets.map(cs => ({ + id: String(cs.id), + type: "changeset", + latLngBounds: L.latLngBounds( + [cs.min_lat, cs.min_lon], + [cs.max_lat, cs.max_lon] + ), + tags: this.getTags(cs) + })); + }, + + getNodes(json) { + const nodes = json.elements?.filter(el => el.type === "node") ?? []; + let result = {}; + + for (const node of nodes) { + result[node.id] = { + id: String(node.id), + type: "node", + latLng: L.latLng(node.lat, node.lon, true), + tags: this.getTags(node) + }; + } + + return result; + }, + + getWays(json, nodes) { + const ways = json.elements?.filter(el => el.type === "way") ?? []; + + return ways.map(way => ({ + id: String(way.id), + type: "way", + nodes: way.nodes.map(nodeId => nodes[nodeId]), + tags: this.getTags(way) + })); + }, + + getRelations(json, nodes, ways) { + const relations = json.elements?.filter(el => el.type === "relation") ?? []; + + return relations.map(rel => ({ + id: String(rel.id), + type: "relation", + members: (rel.members ?? []) // relation-way and relation-relation membership not implemented + .map(member => member.type === "node" ? nodes[member.ref] : null) + .filter(Boolean), // filter out null and undefined + tags: this.getTags(rel) + })); + }, + + getTags(json) { + return json.tags ?? {}; + } +}; diff --git a/package-lock.json b/package-lock.json index fd5a78a..2143a69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,10 +13,8 @@ "devDependencies": { "chai": "^4.2.0", "jsdom": "^16.2.2", + "jsdom-global": "^3.0.2", "mocha": "^10.7.3" - }, - "engines": { - "node": "~0.8.4" } }, "node_modules/@tootallnate/once": { @@ -890,6 +888,15 @@ } } }, + "node_modules/jsdom-global": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsdom-global/-/jsdom-global-3.0.2.tgz", + "integrity": "sha512-t1KMcBkz/pT5JrvcJbpUR2u/w1kO9jXctaaGJ0vZDzwFnIvGWw9IDSRciT83kIs8Bnw4qpOl8bQK08V01YgMPg==", + "dev": true, + "peerDependencies": { + "jsdom": ">=10.0.0" + } + }, "node_modules/leaflet": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-0.6.4.tgz", diff --git a/package.json b/package.json index 6b5875f..2879064 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,9 @@ "leaflet": "0.6" }, "devDependencies": { - "mocha": "^10.7.3", "chai": "^4.2.0", - "jsdom": "^16.2.2" - }, - "optionalDependencies": {} + "jsdom": "^16.2.2", + "jsdom-global": "^3.0.2", + "mocha": "^10.7.3" + } } diff --git a/test/fixtures/area.json b/test/fixtures/area.json new file mode 100644 index 0000000..45514a7 --- /dev/null +++ b/test/fixtures/area.json @@ -0,0 +1 @@ +{"version":"0.6","generator":"OpenStreetMap server","copyright":"OpenStreetMap and contributors","attribution":"http://www.openstreetmap.org/copyright","license":"http://opendatacommons.org/licenses/odbl/1-0/","elements":[{"type":"node","id":1911003400,"lat":44.6641548,"lon":-73.0149544,"timestamp":"2012-09-12T04:59:23Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003422,"lat":44.6639106,"lon":-73.0183662,"timestamp":"2012-09-12T04:59:23Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003428,"lat":44.6639144,"lon":-73.0164457,"timestamp":"2012-09-12T04:59:24Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003434,"lat":44.6632593,"lon":-73.0149372,"timestamp":"2012-09-12T04:59:24Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003459,"lat":44.6642311,"lon":-73.0152709,"timestamp":"2012-09-12T04:59:24Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003477,"lat":44.6639881,"lon":-73.0163749,"timestamp":"2012-09-12T04:59:24Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003481,"lat":44.6640251,"lon":-73.0181462,"timestamp":"2012-09-12T04:59:25Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003483,"lat":44.6640861,"lon":-73.0163599,"timestamp":"2012-09-12T04:59:25Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003505,"lat":44.663365,"lon":-73.0184144,"timestamp":"2012-09-12T04:59:25Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003534,"lat":44.6631742,"lon":-73.0151529,"timestamp":"2012-09-12T04:59:26Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003542,"lat":44.6631857,"lon":-73.0149866,"timestamp":"2012-09-12T04:59:26Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003614,"lat":44.6640251,"lon":-73.018275,"timestamp":"2012-09-12T04:59:27Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003629,"lat":44.6639945,"lon":-73.0183447,"timestamp":"2012-09-12T04:59:27Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"node","id":1911003725,"lat":44.6633765,"lon":-73.0149061,"timestamp":"2012-09-12T04:59:29Z","version":1,"changeset":13078014,"user":"jfire","uid":67236},{"type":"way","id":180655479,"timestamp":"2012-09-12T04:59:32Z","version":1,"changeset":13078014,"user":"jfire","uid":67236,"nodes":[1911003422,1911003505,1911003534,1911003542,1911003434,1911003725,1911003400,1911003459,1911003483,1911003477,1911003428,1911003481,1911003614,1911003629,1911003422],"tags":{"leisure":"pitch"}}]} diff --git a/test/fixtures/changeset.json b/test/fixtures/changeset.json new file mode 100644 index 0000000..96bb8ab --- /dev/null +++ b/test/fixtures/changeset.json @@ -0,0 +1 @@ +{"version":"0.6","generator":"openstreetmap-cgimap 2.0.1 (3448772 spike-06.openstreetmap.org)","copyright":"OpenStreetMap and contributors","attribution":"http://www.openstreetmap.org/copyright","license":"http://opendatacommons.org/licenses/odbl/1-0/","changeset":{"id":1,"created_at":"2005-04-09T19:54:13Z","open":false,"comments_count":48,"changes_count":2,"closed_at":"2005-04-09T20:54:39Z","min_lat":51.5288506,"min_lon":-0.1465242,"max_lat":51.5288620,"max_lon":-0.1464925,"uid":1,"user":"Steve"}} \ No newline at end of file diff --git a/test/fixtures/node.json b/test/fixtures/node.json new file mode 100644 index 0000000..4a14840 --- /dev/null +++ b/test/fixtures/node.json @@ -0,0 +1 @@ +{"version":"0.6","generator":"OpenStreetMap server","copyright":"OpenStreetMap and contributors","attribution":"http://www.openstreetmap.org/copyright","license":"http://opendatacommons.org/licenses/odbl/1-0/","elements":[{"type":"node","id":356552551,"lat":44.6636172,"lon":-73.0132525,"timestamp":"2009-03-07T03:26:33Z","version":1,"changeset":747176,"user":"iandees","uid":4732,"tags":{"amenity":"school","ele":"114","gnis:county_id":"011","gnis:created":"10/29/1980","gnis:edited":"05/27/2008","gnis:feature_id":"1456383","gnis:state_id":"50","name":"Bellows Free Academy"}}]} \ No newline at end of file diff --git a/test/fixtures/way.json b/test/fixtures/way.json new file mode 100644 index 0000000..1b72392 --- /dev/null +++ b/test/fixtures/way.json @@ -0,0 +1 @@ +{"version":"0.6","generator":"OpenStreetMap server","copyright":"OpenStreetMap and contributors","attribution":"http://www.openstreetmap.org/copyright","license":"http://opendatacommons.org/licenses/odbl/1-0/","elements":[{"type":"node","id":204587613,"lat":44.665983,"lon":-72.920587,"timestamp":"2009-10-11T18:01:27Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595896,"lat":44.665883,"lon":-72.923053,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595901,"lat":44.66597,"lon":-72.922201,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595904,"lat":44.665989,"lon":-72.921986,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595911,"lat":44.666015,"lon":-72.921474,"timestamp":"2009-11-17T05:45:06Z","version":2,"changeset":3138486,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595915,"lat":44.666015,"lon":-72.921254,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595919,"lat":44.666007,"lon":-72.921033,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595923,"lat":44.665938,"lon":-72.920089,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595927,"lat":44.665901,"lon":-72.919727,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595932,"lat":44.665837,"lon":-72.919284,"timestamp":"2009-11-17T05:45:06Z","version":2,"changeset":3138486,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595935,"lat":44.665821,"lon":-72.91914,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595939,"lat":44.66581,"lon":-72.918999,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595943,"lat":44.665814,"lon":-72.918855,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595947,"lat":44.665823,"lon":-72.918783,"timestamp":"2009-12-11T06:32:30Z","version":2,"changeset":3346870,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595950,"lat":44.665839,"lon":-72.91871,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595953,"lat":44.66587,"lon":-72.918641,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595955,"lat":44.665923,"lon":-72.918586,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595957,"lat":44.665985,"lon":-72.918559,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595961,"lat":44.666193,"lon":-72.918523,"timestamp":"2009-11-17T05:45:06Z","version":2,"changeset":3138486,"user":"woodpeck_fixbot","uid":147510},{"type":"node","id":204595963,"lat":44.666342,"lon":-72.918513,"timestamp":"2009-10-11T18:03:23Z","version":2,"changeset":2817006,"user":"woodpeck_fixbot","uid":147510},{"type":"way","id":19698713,"timestamp":"2008-01-03T05:24:43Z","version":1,"changeset":522559,"user":"DaveHansenTiger","uid":7168,"nodes":[204595896,204595901,204595904,204595911,204595915,204595919,204587613,204595923,204595927,204595932,204595935,204595939,204595943,204595947,204595950,204595953,204595955,204595957,204595961,204595963],"tags":{"name":"Oustinoff Rd","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070830","tiger:tlid":"136533324:136533325","tiger:upload_uuid":"bulk_upload.pl-62def9fe-abee-42f3-ac1f-9d9f4b4ee78b","tiger:reviewed":"no","tiger:cfcc":"A41","tiger:county":"Franklin, VT","tiger:zip_left":"05444","tiger:zip_right":"05444","highway":"residential","tiger:name_base":"Oustinoff","tiger:name_type":"Rd"}}]} diff --git a/test/osm_test.js b/test/osm_test.js index 34f4cb3..36597fa 100644 --- a/test/osm_test.js +++ b/test/osm_test.js @@ -1,3 +1,5 @@ +require('jsdom-global')() + var chai = require('chai'), jsdom = require("jsdom"), dom = new jsdom.JSDOM; @@ -5,6 +7,7 @@ var chai = require('chai'), global.window = dom.window; global.document = window.document; global.navigator = window.navigator; +global.Document = window.Document; L = require('leaflet'); require('..'); @@ -67,174 +70,183 @@ describe("L.OSM.TracestrackTopo", function () { }); }); -describe("L.OSM.DataLayer", function () { - function fixture(name) { - var fs = require("fs"); - var contents = fs.readFileSync(__dirname + "/fixtures/" + name + ".xml", "utf8"); - var dom = new jsdom.JSDOM(contents, { contentType: "text/xml"}); - return dom.window.document; - } - - function layers(layerGroup) { - var layers = []; - layerGroup.eachLayer(function (layer) { - layers.push(layer); - }); - return layers; - } - - beforeEach(function () { - this.map = L.map(document.createElement("div")); - }); - - it("is can be added to the map", function () { - (new L.OSM.DataLayer()).addTo(this.map); - }); - - it("creates a Polyline for a way", function () { - var osm = new L.OSM.DataLayer(fixture("way")); - layers(osm).length.should.eq(1); - layers(osm)[0].should.be.an.instanceof(L.Polyline); - }); - - it("creates a Polygon for an area", function () { - var osm = new L.OSM.DataLayer(fixture("area")); - layers(osm).length.should.eq(1); - layers(osm)[0].should.be.an.instanceof(L.Polygon); - }); - - it("creates a CircleMarker for an interesting node", function () { - var osm = new L.OSM.DataLayer(fixture("node")); - layers(osm).length.should.eq(1); - layers(osm)[0].should.be.an.instanceof(L.CircleMarker); - }); - - it("creates a Rectangle for a changeset", function () { - var osm = new L.OSM.DataLayer(fixture("changeset")); - layers(osm).length.should.eq(1); - layers(osm)[0].should.be.an.instanceof(L.Rectangle); - }); - - it("sets the feature property on a layer", function () { - var osm = new L.OSM.DataLayer(fixture("node")); - layers(osm)[0].feature.should.have.property("type", "node"); - layers(osm)[0].feature.should.have.property("id", "356552551"); - }); - - it("sets a way's style", function () { - var osm = new L.OSM.DataLayer(fixture("way"), {styles: {way: {color: "red"}}}); - layers(osm)[0].options.should.have.property("color", "red"); - }); - - it("sets an area's style", function () { - var osm = new L.OSM.DataLayer(fixture("area"), {styles: {area: {color: "green"}}}); - layers(osm)[0].options.should.have.property("color", "green"); - }); - - it("sets a node's style", function () { - var osm = new L.OSM.DataLayer(fixture("node"), {styles: {node: {color: "blue"}}}); - layers(osm)[0].options.should.have.property("color", "blue"); - }); +[ "xml", "json"].forEach(format => { + + describe(`L.OSM.DataLayer (${format})`, function () { + function fixture(name) { + var fs = require("fs"); + var contents = fs.readFileSync(__dirname + "/fixtures/" + name + "." + format, "utf8"); + if (format === "xml") { + const parser = new window.DOMParser(); + return parser.parseFromString(contents, "text/xml"); + } + else + { + return JSON.parse(contents); + } + } - describe("asynchronously", function() { - function sleep(time = 0) { - return new Promise(res => { - setTimeout(() => res(), time); + function layers(layerGroup) { + var layers = []; + layerGroup.eachLayer(function (layer) { + layers.push(layer); }); + return layers; } - it("can be added to the map", function () { - (new L.OSM.DataLayer(null, {asynchronous: true})).addTo(this.map); + beforeEach(function () { + this.map = L.map(document.createElement("div")); + }); + + it("is can be added to the map", function () { + (new L.OSM.DataLayer()).addTo(this.map); }); - it("creates a Polyline for a way", async function () { - var osm = new L.OSM.DataLayer(fixture("way"), {asynchronous: true}); - await sleep(1); + it("creates a Polyline for a way", function () { + var osm = new L.OSM.DataLayer(fixture("way")); layers(osm).length.should.eq(1); layers(osm)[0].should.be.an.instanceof(L.Polyline); }); - it("creates a Polygon for an area", async function () { - var osm = new L.OSM.DataLayer(fixture("area"), {asynchronous: true}); - await sleep(1); + it("creates a Polygon for an area", function () { + var osm = new L.OSM.DataLayer(fixture("area")); layers(osm).length.should.eq(1); layers(osm)[0].should.be.an.instanceof(L.Polygon); }); - it("creates a CircleMarker for an interesting node", async function () { - var osm = new L.OSM.DataLayer(fixture("node"), {asynchronous: true}); - await sleep(1); + it("creates a CircleMarker for an interesting node", function () { + var osm = new L.OSM.DataLayer(fixture("node")); layers(osm).length.should.eq(1); layers(osm)[0].should.be.an.instanceof(L.CircleMarker); }); - it("creates a Rectangle for a changeset", async function () { - var osm = new L.OSM.DataLayer(fixture("changeset"), {asynchronous: true}); - await sleep(1); + it("creates a Rectangle for a changeset", function () { + var osm = new L.OSM.DataLayer(fixture("changeset")); layers(osm).length.should.eq(1); layers(osm)[0].should.be.an.instanceof(L.Rectangle); }); - it("sets the feature property on a layer", async function () { - var osm = new L.OSM.DataLayer(fixture("node"), {asynchronous: true}); - await sleep(1); + it("sets the feature property on a layer", function () { + var osm = new L.OSM.DataLayer(fixture("node")); layers(osm)[0].feature.should.have.property("type", "node"); layers(osm)[0].feature.should.have.property("id", "356552551"); }); - it("sets a way's style", async function () { - var osm = new L.OSM.DataLayer(fixture("way"), {styles: {way: {color: "red"}}, asynchronous: true}); - await sleep(1); + it("sets a way's style", function () { + var osm = new L.OSM.DataLayer(fixture("way"), {styles: {way: {color: "red"}}}); layers(osm)[0].options.should.have.property("color", "red"); }); - it("sets an area's style", async function () { - var osm = new L.OSM.DataLayer(fixture("area"), {styles: {area: {color: "green"}}, asynchronous: true}); - await sleep(1); + it("sets an area's style", function () { + var osm = new L.OSM.DataLayer(fixture("area"), {styles: {area: {color: "green"}}}); layers(osm)[0].options.should.have.property("color", "green"); }); - it("sets a node's style", async function () { - var osm = new L.OSM.DataLayer(fixture("node"), {styles: {node: {color: "blue"}}, asynchronous: true}); - await sleep(1); + it("sets a node's style", function () { + var osm = new L.OSM.DataLayer(fixture("node"), {styles: {node: {color: "blue"}}}); layers(osm)[0].options.should.have.property("color", "blue"); }); - }); - describe("#buildFeatures", function () { - it("builds a node object", function () { - var features = new L.OSM.DataLayer().buildFeatures(fixture("node")); - features.length.should.eq(1); - features[0].type.should.eq("node"); - }); + describe("asynchronously", function() { + function sleep(time = 0) { + return new Promise(res => { + setTimeout(() => res(), time); + }); + } - it("builds a way object", function () { - var features = new L.OSM.DataLayer().buildFeatures(fixture("way")); - features.length.should.eq(1); - features[0].type.should.eq("way"); - }); - }); + it("can be added to the map", function () { + (new L.OSM.DataLayer(null, {asynchronous: true})).addTo(this.map); + }); - describe("#interestingNode", function () { - var layer = new L.OSM.DataLayer(); + it("creates a Polyline for a way", async function () { + var osm = new L.OSM.DataLayer(fixture("way"), {asynchronous: true}); + await sleep(1); + layers(osm).length.should.eq(1); + layers(osm)[0].should.be.an.instanceof(L.Polyline); + }); - it("returns true when the node is not in any ways", function () { - layer.interestingNode({id: 1}, {}, {}).should.be.true; - }); + it("creates a Polygon for an area", async function () { + var osm = new L.OSM.DataLayer(fixture("area"), {asynchronous: true}); + await sleep(1); + layers(osm).length.should.eq(1); + layers(osm)[0].should.be.an.instanceof(L.Polygon); + }); + + it("creates a CircleMarker for an interesting node", async function () { + var osm = new L.OSM.DataLayer(fixture("node"), {asynchronous: true}); + await sleep(1); + layers(osm).length.should.eq(1); + layers(osm)[0].should.be.an.instanceof(L.CircleMarker); + }); + + it("creates a Rectangle for a changeset", async function () { + var osm = new L.OSM.DataLayer(fixture("changeset"), {asynchronous: true}); + await sleep(1); + layers(osm).length.should.eq(1); + layers(osm)[0].should.be.an.instanceof(L.Rectangle); + }); + + it("sets the feature property on a layer", async function () { + var osm = new L.OSM.DataLayer(fixture("node"), {asynchronous: true}); + await sleep(1); + layers(osm)[0].feature.should.have.property("type", "node"); + layers(osm)[0].feature.should.have.property("id", "356552551"); + }); + + it("sets a way's style", async function () { + var osm = new L.OSM.DataLayer(fixture("way"), {styles: {way: {color: "red"}}, asynchronous: true}); + await sleep(1); + layers(osm)[0].options.should.have.property("color", "red"); + }); + + it("sets an area's style", async function () { + var osm = new L.OSM.DataLayer(fixture("area"), {styles: {area: {color: "green"}}, asynchronous: true}); + await sleep(1); + layers(osm)[0].options.should.have.property("color", "green"); + }); - it("returns true when the node has an interesting tag", function () { - var node = {id: 1, tags: {interesting: true}}; - layer.interestingNode(node, {1: true}, {1: true}).should.be.true; + it("sets a node's style", async function () { + var osm = new L.OSM.DataLayer(fixture("node"), {styles: {node: {color: "blue"}}, asynchronous: true}); + await sleep(1); + layers(osm)[0].options.should.have.property("color", "blue"); + }); }); - it("returns false when the node is used in a way and has uninteresting tags", function () { - var node = {id: 1, tags: {source: 'who cares?'}}; - layer.interestingNode(node, {1: true}, {}).should.be.false; + describe("#buildFeatures", function () { + it("builds a node object", function () { + var features = new L.OSM.DataLayer().buildFeatures(fixture("node")); + features.length.should.eq(1); + features[0].type.should.eq("node"); + }); + + it("builds a way object", function () { + var features = new L.OSM.DataLayer().buildFeatures(fixture("way")); + features.length.should.eq(1); + features[0].type.should.eq("way"); + }); }); - it("returns true when the node is used in a way and is used in a relation", function () { - var node = {id: 1}; - layer.interestingNode(node, {1: true}, {1: true}).should.be.true; + describe("#interestingNode", function () { + var layer = new L.OSM.DataLayer(); + + it("returns true when the node is not in any ways", function () { + layer.interestingNode({id: 1}, {}, {}).should.be.true; + }); + + it("returns true when the node has an interesting tag", function () { + var node = {id: 1, tags: {interesting: true}}; + layer.interestingNode(node, {1: true}, {1: true}).should.be.true; + }); + + it("returns false when the node is used in a way and has uninteresting tags", function () { + var node = {id: 1, tags: {source: 'who cares?'}}; + layer.interestingNode(node, {1: true}, {}).should.be.false; + }); + + it("returns true when the node is used in a way and is used in a relation", function () { + var node = {id: 1}; + layer.interestingNode(node, {1: true}, {1: true}).should.be.true; + }); }); }); -}); +}); \ No newline at end of file