WIP on external presets

- preset data is no longer bundled into iD.js
- some code pathways commented out re: external presets
- many changes so that tests can run without presets at start, or async
- still need to make sure fallbacks are always there (point, line, area, etc)
This commit is contained in:
Bryan Housel
2020-02-05 09:38:26 -05:00
parent a333a341ec
commit 0fe766d9a4
21 changed files with 1435 additions and 1435 deletions
+14 -6
View File
@@ -1,4 +1,16 @@
describe('iD.osmWay', function() {
var _savedAreaKeys;
before(function() {
_savedAreaKeys = iD.osmAreaKeys;
iD.osmSetAreaKeys({ building: {} });
});
after(function() {
iD.osmSetAreaKeys(_savedAreaKeys);
});
if (iD.debug) {
it('freezes nodes', function () {
expect(Object.isFrozen(iD.osmWay().nodes)).to.be.true;
@@ -405,10 +417,6 @@ describe('iD.osmWay', function() {
});
describe('#isArea', function() {
before(function() {
iD.coreContext().init();
});
it('returns false when the way has no tags', function() {
expect(iD.osmWay().isArea()).to.equal(false);
});
@@ -421,7 +429,7 @@ describe('iD.osmWay', function() {
expect(iD.osmWay({nodes: ['n1', 'n1']}).isArea()).to.equal(false);
});
it('returns true if the way is closed and has a key in iD.areaKeys', function() {
it('returns true if the way is closed and has a key in iD.osmAreaKeys', function() {
expect(iD.osmWay({nodes: ['n1', 'n1'], tags: {building: 'yes'}}).isArea()).to.equal(true);
});
@@ -435,7 +443,7 @@ describe('iD.osmWay', function() {
expect(iD.osmWay({nodes: ['n1', 'n1'], tags: { railway: 'wash' }}).isArea(), 'railway=wash').to.equal(true);
});
it('returns false if the way is closed and has no keys in iD.areaKeys', function() {
it('returns false if the way is closed and has no keys in iD.osmAreaKeys', function() {
expect(iD.osmWay({nodes: ['n1', 'n1'], tags: {a: 'b'}}).isArea()).to.equal(false);
});
+151 -109
View File
@@ -1,132 +1,162 @@
describe('iD.presetIndex', function () {
var savedPresets, savedAreaKeys, server;
var _savedPresets, _savedAreaKeys;
before(function () {
savedPresets = iD.data.presets;
savedAreaKeys = iD.areaKeys;
before(function() {
_savedPresets = iD.data.preset_presets;
_savedAreaKeys = iD.osmAreaKeys;
});
after(function () {
iD.data.presets = savedPresets;
iD.setAreaKeys(savedAreaKeys);
after(function() {
iD.data.preset_presets = _savedPresets;
iD.osmSetAreaKeys(_savedAreaKeys);
});
describe('#match', function () {
var testPresets = {
presets: {
point: { tags: {}, geometry: ['point'] },
line: { tags: {}, geometry: ['line'] },
vertex: { tags: {}, geometry: ['vertex'] },
residential: { tags: { highway: 'residential' }, geometry: ['line'] },
park: { tags: { leisure: 'park' }, geometry: ['point', 'area'] }
}
point: { tags: {}, geometry: ['point'] },
line: { tags: {}, geometry: ['line'] },
vertex: { tags: {}, geometry: ['vertex'] },
residential: { tags: { highway: 'residential' }, geometry: ['line'] },
park: { tags: { leisure: 'park' }, geometry: ['point', 'area'] }
};
it('returns a collection containing presets matching a geometry and tags', function () {
iD.data.presets = testPresets;
it('returns a collection containing presets matching a geometry and tags', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
var way = iD.osmWay({ tags: { highway: 'residential' } });
var graph = iD.coreGraph([way]);
expect(presets.match(way, graph).id).to.eql('residential');
window.setTimeout(function() {
expect(presets.match(way, graph).id).to.eql('residential');
done();
}, 20);
});
it('returns the appropriate fallback preset when no tags match', function () {
iD.data.presets = testPresets;
it('returns the appropriate fallback preset when no tags match', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
var point = iD.osmNode();
var line = iD.osmWay({ tags: { foo: 'bar' } });
var graph = iD.coreGraph([point, line]);
expect(presets.match(point, graph).id).to.eql('point');
expect(presets.match(line, graph).id).to.eql('line');
window.setTimeout(function() {
expect(presets.match(point, graph).id).to.eql('point');
expect(presets.match(line, graph).id).to.eql('line');
done();
}, 20);
});
it('matches vertices on a line as points', function () {
iD.data.presets = testPresets;
it('matches vertices on a line as points', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
var point = iD.osmNode({ tags: { leisure: 'park' } });
var line = iD.osmWay({ nodes: [point.id], tags: { 'highway': 'residential' } });
var graph = iD.coreGraph([point, line]);
expect(presets.match(point, graph).id).to.eql('point');
window.setTimeout(function() {
expect(presets.match(point, graph).id).to.eql('point');
done();
}, 20);
});
it('matches vertices on an addr:interpolation line as points', function () {
iD.data.presets = testPresets;
it('matches vertices on an addr:interpolation line as points', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
var point = iD.osmNode({ tags: { leisure: 'park' } });
var line = iD.osmWay({ nodes: [point.id], tags: { 'addr:interpolation': 'even' } });
var graph = iD.coreGraph([point, line]);
expect(presets.match(point, graph).id).to.eql('park');
window.setTimeout(function() {
expect(presets.match(point, graph).id).to.eql('park');
done();
}, 20);
});
});
describe('#areaKeys', function () {
var testPresets = {
presets: {
'amenity/fuel/shell': { tags: { 'amenity': 'fuel' }, geometry: ['point', 'area'], suggestion: true },
'highway/foo': { tags: { 'highway': 'foo' }, geometry: ['area'] },
'leisure/track': { tags: { 'leisure': 'track' }, geometry: ['line', 'area'] },
'natural': { tags: { 'natural': '*' }, geometry: ['point', 'vertex', 'area'] },
'natural/peak': { tags: { 'natural': 'peak' }, geometry: ['point', 'vertex'] },
'natural/tree_row': { tags: { 'natural': 'tree_row' }, geometry: ['line'] },
'natural/wood': { tags: { 'natural': 'wood' }, geometry: ['point', 'area'] }
}
'amenity/fuel/shell': { tags: { 'amenity': 'fuel' }, geometry: ['point', 'area'], suggestion: true },
'highway/foo': { tags: { 'highway': 'foo' }, geometry: ['area'] },
'leisure/track': { tags: { 'leisure': 'track' }, geometry: ['line', 'area'] },
'natural': { tags: { 'natural': '*' }, geometry: ['point', 'vertex', 'area'] },
'natural/peak': { tags: { 'natural': 'peak' }, geometry: ['point', 'vertex'] },
'natural/tree_row': { tags: { 'natural': 'tree_row' }, geometry: ['line'] },
'natural/wood': { tags: { 'natural': 'wood' }, geometry: ['point', 'area'] }
};
it('whitelists keys for presets with area geometry', function () {
iD.data.presets = testPresets;
it('includes keys for presets with area geometry', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
expect(presets.areaKeys()).to.include.keys('natural');
window.setTimeout(function() {
expect(presets.areaKeys()).to.include.keys('natural');
done();
}, 20);
});
it('blacklists key-values for presets with a line geometry', function () {
iD.data.presets = testPresets;
it('discards key-values for presets with a line geometry', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
expect(presets.areaKeys().natural).to.include.keys('tree_row');
expect(presets.areaKeys().natural.tree_row).to.be.true;
window.setTimeout(function() {
expect(presets.areaKeys().natural).to.include.keys('tree_row');
expect(presets.areaKeys().natural.tree_row).to.be.true;
done();
}, 20);
});
it('blacklists key-values for presets with both area and line geometry', function () {
iD.data.presets = testPresets;
it('discards key-values for presets with both area and line geometry', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
expect(presets.areaKeys().leisure).to.include.keys('track');
window.setTimeout(function() {
expect(presets.areaKeys().leisure).to.include.keys('track');
done();
}, 20);
});
it('does not blacklist key-values for presets with neither area nor line geometry', function () {
iD.data.presets = testPresets;
it('does not discard key-values for presets with neither area nor line geometry', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
expect(presets.areaKeys().natural).not.to.include.keys('peak');
window.setTimeout(function() {
expect(presets.areaKeys().natural).not.to.include.keys('peak');
done();
}, 20);
});
it('does not blacklist generic \'*\' key-values', function () {
iD.data.presets = testPresets;
it('does not discard generic \'*\' key-values', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
expect(presets.areaKeys().natural).not.to.include.keys('natural');
window.setTimeout(function() {
expect(presets.areaKeys().natural).not.to.include.keys('natural');
done();
}, 20);
});
it('ignores keys like \'highway\' that are assumed to be lines', function () {
iD.data.presets = testPresets;
it('ignores keys like \'highway\' that are assumed to be lines', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
expect(presets.areaKeys()).not.to.include.keys('highway');
window.setTimeout(function() {
expect(presets.areaKeys()).not.to.include.keys('highway');
done();
}, 20);
});
it('ignores suggestion presets', function () {
iD.data.presets = testPresets;
it('ignores suggestion presets', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
expect(presets.areaKeys()).not.to.include.keys('amenity');
window.setTimeout(function() {
expect(presets.areaKeys()).not.to.include.keys('amenity');
done();
}, 20);
});
});
describe('#build', function () {
describe.skip('#build', function () {
it('builds presets from provided', function () {
var surfShop = iD.osmNode({ tags: { amenity: 'shop', 'shop:type': 'surf' } });
var graph = iD.coreGraph([surfShop]);
var presets = iD.coreContext().init().presets();
var morePresets = {
var presetData = {
presets: {
'amenity/shop/surf': {
tags: { amenity: 'shop', 'shop:type': 'surf' },
@@ -136,7 +166,7 @@ describe('iD.presetIndex', function () {
};
expect(presets.match(surfShop, graph)).to.eql(undefined); // no surfshop preset yet...
presets.build(morePresets, true);
presets.build(presetData, true);
expect(presets.match(surfShop, graph).addTags).to.eql({ amenity: 'shop', 'shop:type': 'surf' });
});
@@ -146,7 +176,7 @@ describe('iD.presetIndex', function () {
var entities = [surfShop, firstStreetJetty];
var graph = iD.coreGraph(entities);
var presets = iD.coreContext().init().presets();
var morePresets = {
var presetData = {
presets: {
'amenity/shop/surf': {
tags: { amenity: 'shop', 'shop:type': 'surf' },
@@ -159,7 +189,7 @@ describe('iD.presetIndex', function () {
}
};
presets.build(morePresets, false);
presets.build(presetData, false);
entities.forEach(function (entity) {
var preset = presets.match(entity, graph);
expect(preset.addable()).to.be.false;
@@ -167,64 +197,76 @@ describe('iD.presetIndex', function () {
});
});
describe('expected matches', function () {
var testPresets = {
presets: {
area: { name: 'Area', tags: {}, geometry: ['area'] },
line: { name: 'Line', tags: {}, geometry: ['line'] },
point: { name: 'Point', tags: {}, geometry: ['point'] },
vertex: { name: 'Vertex', tags: {}, geometry: ['vertex'] },
relation: { name: 'Relation', tags: {}, geometry: ['relation'] },
building: { name: 'Building', tags: { building: 'yes' }, geometry: ['area'] },
'type/multipolygon': {
name: 'Multipolygon',
geometry: ['area', 'relation'],
tags: { 'type': 'multipolygon' },
searchable: false,
matchScore: 0.1
},
address: {
name: 'Address',
geometry: ['point', 'vertex', 'area'],
tags: { 'addr:*': '*' },
matchScore: 0.15
},
'highway/pedestrian_area': {
name: 'Pedestrian Area',
geometry: ['area'],
tags: { highway: 'pedestrian', area: 'yes' }
}
area: { name: 'Area', tags: {}, geometry: ['area'] },
line: { name: 'Line', tags: {}, geometry: ['line'] },
point: { name: 'Point', tags: {}, geometry: ['point'] },
vertex: { name: 'Vertex', tags: {}, geometry: ['vertex'] },
relation: { name: 'Relation', tags: {}, geometry: ['relation'] },
building: { name: 'Building', tags: { building: 'yes' }, geometry: ['area'] },
'type/multipolygon': {
name: 'Multipolygon',
geometry: ['area', 'relation'],
tags: { 'type': 'multipolygon' },
searchable: false,
matchScore: 0.1
},
address: {
name: 'Address',
geometry: ['point', 'vertex', 'area'],
tags: { 'addr:*': '*' },
matchScore: 0.15
},
'highway/pedestrian_area': {
name: 'Pedestrian Area',
geometry: ['area'],
tags: { highway: 'pedestrian', area: 'yes' }
}
};
it('prefers building to multipolygon', function () {
iD.data.presets = testPresets;
it('prefers building to multipolygon', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
var relation = iD.osmRelation({ tags: { type: 'multipolygon', building: 'yes' } });
var graph = iD.coreGraph([relation]);
expect(presets.match(relation, graph).id).to.eql('building');
window.setTimeout(function() {
var match = presets.match(relation, graph);
expect(match.id).to.eql('building');
done();
}, 20);
});
it('prefers building to address', function () {
iD.data.presets = testPresets;
it('prefers building to address', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
var way = iD.osmWay({ tags: { area: 'yes', building: 'yes', 'addr:housenumber': '1234' } });
var graph = iD.coreGraph([way]);
expect(presets.match(way, graph).id).to.eql('building');
window.setTimeout(function() {
var match = presets.match(way, graph);
expect(match.id).to.eql('building');
done();
}, 20);
});
it('prefers pedestrian to area', function () {
iD.data.presets = testPresets;
it('prefers pedestrian to area', function (done) {
iD.data.preset_presets = testPresets;
var presets = iD.coreContext().init().presets();
var way = iD.osmWay({ tags: { area: 'yes', highway: 'pedestrian' } });
var graph = iD.coreGraph([way]);
expect(presets.match(way, graph).id).to.eql('highway/pedestrian_area');
window.setTimeout(function() {
var match = presets.match(way, graph);
expect(match.id).to.eql('highway/pedestrian_area');
done();
}, 20);
});
});
describe('#fromExternal', function () {
var morePresets = {
describe.skip('#fromExternal', function () {
var _server;
var presetData = {
presets: {
'8bc64d6d': {
'name': 'Surf Shop',
@@ -245,11 +287,11 @@ describe('iD.presetIndex', function () {
};
beforeEach(function () {
server = window.fakeFetch().create();
_server = window.fakeFetch().create();
});
afterEach(function () {
server.restore();
_server.restore();
});
it('builds presets w/external sources set to addable', function () {
@@ -268,10 +310,10 @@ describe('iD.presetIndex', function () {
expect(externalPresets.match(surfShop, graph).id).to.eql('8bc64d6d');
});
server.respondWith('GET', /fake\.json/,
[200, { 'Content-Type': 'application/json' }, JSON.stringify(morePresets)]
_server.respondWith('GET', /fake\.json/,
[200, { 'Content-Type': 'application/json' }, JSON.stringify(presetData)]
);
server.respond();
_server.respond();
});
it('makes only the external presets initially addable', function () {
@@ -285,7 +327,7 @@ describe('iD.presetIndex', function () {
return presets;
}, []);
var morePresetKeys = Object.keys(morePresets.presets);
var morePresetKeys = Object.keys(presetData.presets);
expect(morePresetKeys.length).to.eql(external.length);
morePresetKeys.forEach(function(presetID) {
@@ -293,10 +335,10 @@ describe('iD.presetIndex', function () {
});
});
server.respondWith('GET', /fake\.json/,
[200, { 'Content-Type': 'application/json' }, JSON.stringify(morePresets)]
_server.respondWith('GET', /fake\.json/,
[200, { 'Content-Type': 'application/json' }, JSON.stringify(presetData)]
);
server.respond();
_server.respond();
});
});
+4 -4
View File
@@ -97,15 +97,15 @@ describe('iD.presetPreset', function() {
});
describe('#setTags', function() {
var savedAreaKeys;
var _savedAreaKeys;
before(function () {
savedAreaKeys = iD.areaKeys;
iD.setAreaKeys({ building: {}, natural: {} });
_savedAreaKeys = iD.osmAreaKeys;
iD.osmSetAreaKeys({ building: {}, natural: {} });
});
after(function () {
iD.setAreaKeys(savedAreaKeys);
iD.osmSetAreaKeys(_savedAreaKeys);
});
it('adds match tags', function() {
+4 -4
View File
@@ -1,9 +1,9 @@
describe('maprules', function() {
var _ruleChecks, savedAreaKeys, validationRules;
var _ruleChecks, _savedAreaKeys, validationRules;
before(function() {
savedAreaKeys = iD.areaKeys;
iD.setAreaKeys({ building: {}, amenity: {} });
_savedAreaKeys = iD.osmAreaKeys;
iD.osmSetAreaKeys({ building: {}, amenity: {} });
iD.services.maprules = iD.serviceMapRules;
iD.serviceMapRules.init();
@@ -11,7 +11,7 @@ describe('maprules', function() {
});
after(function() {
iD.setAreaKeys(savedAreaKeys);
iD.osmSetAreaKeys(_savedAreaKeys);
delete iD.services.maprules;
});
+23 -11
View File
@@ -7,19 +7,31 @@ iD.data.imagery = [];
for (var k in iD.services) { delete iD.services[k]; }
// run with a minimal set of presets for speed
iD.data.presets = {
presets: {
area: { name: 'Area', tags: {}, geometry: ['area'] },
line: { name: 'Line', tags: {}, geometry: ['line'] },
point: { name: 'Point', tags: {}, geometry: ['point'] },
vertex: { name: 'Vertex', tags: {}, geometry: ['vertex'] },
relation: { name: 'Relation', tags: {}, geometry: ['relation'] },
// for tests related to areaKeys:
building: { name: 'Building', tags: { building: 'yes' }, geometry: ['point', 'area'] },
man_made: { name: 'Man Made', tags: { man_made: '*' }, geometry: ['vertex', 'point', 'line', 'area'] }
}
// iD.data.presets = {
// presets: {
// area: { name: 'Area', tags: {}, geometry: ['area'] },
// line: { name: 'Line', tags: {}, geometry: ['line'] },
// point: { name: 'Point', tags: {}, geometry: ['point'] },
// vertex: { name: 'Vertex', tags: {}, geometry: ['vertex'] },
// relation: { name: 'Relation', tags: {}, geometry: ['relation'] },
// // for tests related to areaKeys:
// building: { name: 'Building', tags: { building: 'yes' }, geometry: ['point', 'area'] },
// man_made: { name: 'Man Made', tags: { man_made: '*' }, geometry: ['vertex', 'point', 'line', 'area'] }
// }
// };
iD.data.preset_categories = {};
iD.data.preset_defaults = {};
iD.data.preset_fields = {};
iD.data.preset_presets = {
area: { name: 'Area', tags: {}, geometry: ['area'] },
line: { name: 'Line', tags: {}, geometry: ['line'] },
point: { name: 'Point', tags: {}, geometry: ['point'] },
vertex: { name: 'Vertex', tags: {}, geometry: ['vertex'] },
relation: { name: 'Relation', tags: {}, geometry: ['relation'] }
};
// creating `coreContext` creates validators and some of the validators try loading these
iD.data.deprecated = [];
iD.data.nsi_brands = [];
+43 -42
View File
@@ -1,7 +1,8 @@
describe('iD.svgAreas', function () {
var context, surface, savedAreaKeys;
var context, _surface, _savedAreaKeys;
var all = function() { return true; };
var none = function() { return false; };
var projection = d3.geoProjection(function(x, y) { return [x, -y]; })
.translate([0, 0])
.scale(iD.geoZoomToScale(17))
@@ -13,14 +14,14 @@ describe('iD.svgAreas', function () {
d3.select(document.createElement('div'))
.attr('id', 'map')
.call(context.map().centerZoom([0, 0], 17));
surface = context.surface();
_surface = context.surface();
savedAreaKeys = iD.areaKeys;
iD.setAreaKeys({ building: {}, landuse: {}, natural: {} });
_savedAreaKeys = iD.osmAreaKeys;
iD.osmSetAreaKeys({ building: {}, landuse: {}, natural: {} });
});
afterEach(function () {
iD.setAreaKeys(savedAreaKeys);
iD.osmSetAreaKeys(_savedAreaKeys);
});
@@ -30,13 +31,13 @@ describe('iD.svgAreas', function () {
iD.osmNode({id: 'b', loc: [1, 0]}),
iD.osmNode({id: 'c', loc: [1, 1]}),
iD.osmNode({id: 'd', loc: [0, 1]}),
iD.osmWay({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
iD.osmWay({id: 'w', tags: {area: 'yes', building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
]);
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], none);
expect(surface.select('path.way').classed('way')).to.be.true;
expect(surface.select('path.area').classed('area')).to.be.true;
expect(_surface.select('path.way').classed('way')).to.be.true;
expect(_surface.select('path.area').classed('area')).to.be.true;
});
it('adds tag classes', function () {
@@ -45,13 +46,13 @@ describe('iD.svgAreas', function () {
iD.osmNode({id: 'b', loc: [1, 0]}),
iD.osmNode({id: 'c', loc: [1, 1]}),
iD.osmNode({id: 'd', loc: [0, 1]}),
iD.osmWay({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
iD.osmWay({id: 'w', tags: {area: 'yes', building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
]);
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], none);
expect(surface.select('.area').classed('tag-building')).to.be.true;
expect(surface.select('.area').classed('tag-building-yes')).to.be.true;
expect(_surface.select('.area').classed('tag-building')).to.be.true;
expect(_surface.select('.area').classed('tag-building-yes')).to.be.true;
});
it('handles deletion of a way and a member vertex (#1903)', function () {
@@ -64,11 +65,11 @@ describe('iD.svgAreas', function () {
iD.osmWay({id: 'x', tags: {area: 'yes'}, nodes: ['a', 'b', 'd', 'a']})
]);
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('x')], all);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('x')], all);
graph = graph.remove(graph.entity('x')).remove(graph.entity('d'));
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], all);
expect(surface.select('.area').size()).to.equal(1);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], all);
expect(_surface.select('.area').size()).to.equal(1);
});
describe('z-indexing', function() {
@@ -81,38 +82,38 @@ describe('iD.svgAreas', function () {
iD.osmNode({id: 'f', loc: [ 0.0004, 0.0002]}),
iD.osmNode({id: 'g', loc: [ 0.0004, -0.0002]}),
iD.osmNode({id: 'h', loc: [-0.0004, -0.0002]}),
iD.osmWay({id: 's', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']}),
iD.osmWay({id: 'l', tags: {landuse: 'park'}, nodes: ['e', 'f', 'g', 'h', 'e']})
iD.osmWay({id: 's', tags: {area: 'yes', building: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']}),
iD.osmWay({id: 'l', tags: {area: 'yes', landuse: 'park'}, nodes: ['e', 'f', 'g', 'h', 'e']})
]);
it('stacks smaller areas above larger ones in a single render', function () {
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('s'), graph.entity('l')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('s'), graph.entity('l')], none);
expect(surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
expect(_surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(_surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
});
it('stacks smaller areas above larger ones in a single render (reverse)', function () {
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('l'), graph.entity('s')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('l'), graph.entity('s')], none);
expect(surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
expect(_surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(_surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
});
it('stacks smaller areas above larger ones in separate renders', function () {
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('s')], none);
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('l')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('s')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('l')], none);
expect(surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
expect(_surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(_surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
});
it('stacks smaller areas above larger ones in separate renders (reverse)', function () {
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('l')], none);
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('s')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('l')], none);
_surface.call(iD.svgAreas(projection, context), graph, [graph.entity('s')], none);
expect(surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
expect(_surface.select('.area:nth-child(1)').classed('tag-landuse-park')).to.be.true;
expect(_surface.select('.area:nth-child(2)').classed('tag-building-yes')).to.be.true;
});
});
@@ -125,9 +126,9 @@ describe('iD.svgAreas', function () {
var graph = iD.coreGraph([a, b, c, w, r]);
var areas = [w, r];
surface.call(iD.svgAreas(projection, context), graph, areas, none);
_surface.call(iD.svgAreas(projection, context), graph, areas, none);
expect(surface.select('.fill').classed('relation')).to.be.true;
expect(_surface.select('.fill').classed('relation')).to.be.true;
});
it('renders no strokes for multipolygon areas', function () {
@@ -139,9 +140,9 @@ describe('iD.svgAreas', function () {
var graph = iD.coreGraph([a, b, c, w, r]);
var areas = [w, r];
surface.call(iD.svgAreas(projection, context), graph, areas, none);
_surface.call(iD.svgAreas(projection, context), graph, areas, none);
expect(surface.selectAll('.stroke').size()).to.equal(0);
expect(_surface.selectAll('.stroke').size()).to.equal(0);
});
it('renders fill for a multipolygon with tags on the outer way', function() {
@@ -152,11 +153,11 @@ describe('iD.svgAreas', function () {
var r = iD.osmRelation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}});
var graph = iD.coreGraph([a, b, c, w, r]);
surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
_surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
expect(surface.selectAll('.way.fill').size()).to.equal(0);
expect(surface.selectAll('.relation.fill').size()).to.equal(1);
expect(surface.select('.relation.fill').classed('tag-natural-wood')).to.be.true;
expect(_surface.selectAll('.way.fill').size()).to.equal(0);
expect(_surface.selectAll('.relation.fill').size()).to.equal(1);
expect(_surface.select('.relation.fill').classed('tag-natural-wood')).to.be.true;
});
it('renders no strokes for a multipolygon with tags on the outer way', function() {
@@ -167,8 +168,8 @@ describe('iD.svgAreas', function () {
var r = iD.osmRelation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}});
var graph = iD.coreGraph([a, b, c, w, r]);
surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
_surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
expect(surface.selectAll('.stroke').size()).to.equal(0);
expect(_surface.selectAll('.stroke').size()).to.equal(0);
});
});
+8 -1
View File
@@ -1,10 +1,16 @@
describe('iD.validations.mismatched_geometry', function () {
var context;
var context, _savedAreaKeys;
beforeEach(function() {
_savedAreaKeys = iD.osmAreaKeys;
context = iD.coreContext().init();
});
afterEach(function() {
iD.osmSetAreaKeys(_savedAreaKeys);
});
function createPoint(tags) {
var n1 = iD.osmNode({id: 'n-1', loc: [4,4], tags: tags});
context.perform(
@@ -82,6 +88,7 @@ describe('iD.validations.mismatched_geometry', function () {
});
it('flags open way with area tag', function() {
iD.osmSetAreaKeys({ building: {} });
createOpenWay({ building: 'yes' });
var issues = validate();
expect(issues).to.have.lengthOf(1);