mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
fixed more tests
This commit is contained in:
@@ -75,7 +75,7 @@ module.exports = function (config) {
|
||||
// available browser launchers: https://www.npmjs.com/search?q=keywords:karma-launcher
|
||||
browsers: [
|
||||
'Chrome',
|
||||
// 'PhantomJS'
|
||||
'PhantomJS'
|
||||
],
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@ function abortRequest(controller) {
|
||||
|
||||
|
||||
function maxPageAtZoom(z) {
|
||||
if (z < 15) return 2;
|
||||
if (z < 15) return 2;
|
||||
if (z === 15) return 5;
|
||||
if (z === 16) return 10;
|
||||
if (z === 17) return 20;
|
||||
if (z === 18) return 40;
|
||||
if (z > 18) return 80;
|
||||
if (z > 18) return 80;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,15 +44,15 @@ function loadTiles(which, url, projection) {
|
||||
|
||||
// abort inflight requests that are no longer needed
|
||||
var cache = _oscCache[which];
|
||||
Object.keys(cache.inflight).forEach(function(k) {
|
||||
var wanted = tiles.find(function(tile) { return k.indexOf(tile.id + ',') === 0; });
|
||||
Object.keys(cache.inflight).forEach(function (k) {
|
||||
var wanted = tiles.find(function (tile) { return k.indexOf(tile.id + ',') === 0; });
|
||||
if (!wanted) {
|
||||
abortRequest(cache.inflight[k]);
|
||||
delete cache.inflight[k];
|
||||
}
|
||||
});
|
||||
|
||||
tiles.forEach(function(tile) {
|
||||
tiles.forEach(function (tile) {
|
||||
loadNextTilePage(which, currZoom, url, tile);
|
||||
});
|
||||
}
|
||||
@@ -87,14 +87,14 @@ function loadNextTilePage(which, currZoom, url, tile) {
|
||||
};
|
||||
|
||||
d3_json(url, options)
|
||||
.then(function(data) {
|
||||
.then(function (data) {
|
||||
cache.loaded[id] = true;
|
||||
delete cache.inflight[id];
|
||||
if (!data || !data.currentPageItems || !data.currentPageItems.length) {
|
||||
throw new Error('No Data');
|
||||
}
|
||||
|
||||
var features = data.currentPageItems.map(function(item) {
|
||||
var features = data.currentPageItems.map(function (item) {
|
||||
var loc = [+item.lng, +item.lat];
|
||||
var d;
|
||||
|
||||
@@ -138,7 +138,7 @@ function loadNextTilePage(which, currZoom, url, tile) {
|
||||
dispatch.call('loadedImages');
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
.catch(function () {
|
||||
cache.loaded[id] = true;
|
||||
delete cache.inflight[id];
|
||||
});
|
||||
@@ -152,7 +152,7 @@ function partitionViewport(projection) {
|
||||
var tiler = utilTiler().zoomExtent([z2, z2]);
|
||||
|
||||
return tiler.getTiles(projection)
|
||||
.map(function(tile) { return tile.extent; });
|
||||
.map(function (tile) { return tile.extent; });
|
||||
}
|
||||
|
||||
|
||||
@@ -161,10 +161,10 @@ function searchLimited(limit, projection, rtree) {
|
||||
limit = limit || 5;
|
||||
|
||||
return partitionViewport(projection)
|
||||
.reduce(function(result, extent) {
|
||||
.reduce(function (result, extent) {
|
||||
var found = rtree.search(extent.bbox())
|
||||
.slice(0, limit)
|
||||
.map(function(d) { return d.data; });
|
||||
.map(function (d) { return d.data; });
|
||||
|
||||
return (found.length ? result.concat(found) : result);
|
||||
}, []);
|
||||
@@ -173,7 +173,7 @@ function searchLimited(limit, projection, rtree) {
|
||||
|
||||
export default {
|
||||
|
||||
init: function() {
|
||||
init: function () {
|
||||
if (!_oscCache) {
|
||||
this.reset();
|
||||
}
|
||||
@@ -181,7 +181,7 @@ export default {
|
||||
this.event = utilRebind(this, dispatch, 'on');
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset: function () {
|
||||
if (_oscCache) {
|
||||
Object.values(_oscCache.images.inflight).forEach(abortRequest);
|
||||
}
|
||||
@@ -195,13 +195,13 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
images: function(projection) {
|
||||
images: function (projection) {
|
||||
var limit = 5;
|
||||
return searchLimited(limit, projection, _oscCache.images.rtree);
|
||||
},
|
||||
|
||||
|
||||
sequences: function(projection) {
|
||||
sequences: function (projection) {
|
||||
var viewport = projection.clipExtent();
|
||||
var min = [viewport[0][0], viewport[1][1]];
|
||||
var max = [viewport[1][0], viewport[0][1]];
|
||||
@@ -210,12 +210,12 @@ export default {
|
||||
|
||||
// all sequences for images in viewport
|
||||
_oscCache.images.rtree.search(bbox)
|
||||
.forEach(function(d) { sequenceKeys[d.data.sequence_id] = true; });
|
||||
.forEach(function (d) { sequenceKeys[d.data.sequence_id] = true; });
|
||||
|
||||
// make linestrings from those sequences
|
||||
var lineStrings = [];
|
||||
Object.keys(sequenceKeys)
|
||||
.forEach(function(sequenceKey) {
|
||||
.forEach(function (sequenceKey) {
|
||||
var seq = _oscCache.sequences[sequenceKey];
|
||||
var images = seq && seq.images;
|
||||
|
||||
@@ -224,8 +224,8 @@ export default {
|
||||
type: 'LineString',
|
||||
coordinates: images.map(function (d) { return d.loc; }).filter(Boolean),
|
||||
properties: {
|
||||
captured_at: images[0] ? images[0].captured_at: null,
|
||||
captured_by: images[0] ? images[0].captured_by: null,
|
||||
captured_at: images[0] ? images[0].captured_at : null,
|
||||
captured_by: images[0] ? images[0].captured_by : null,
|
||||
key: sequenceKey
|
||||
}
|
||||
});
|
||||
@@ -235,18 +235,18 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
cachedImage: function(imageKey) {
|
||||
cachedImage: function (imageKey) {
|
||||
return _oscCache.images.forImageKey[imageKey];
|
||||
},
|
||||
|
||||
|
||||
loadImages: function(projection) {
|
||||
loadImages: function (projection) {
|
||||
var url = apibase + '/1.0/list/nearby-photos/';
|
||||
loadTiles('images', url, projection);
|
||||
},
|
||||
|
||||
|
||||
ensureViewerLoaded: function(context) {
|
||||
ensureViewerLoaded: function (context) {
|
||||
|
||||
if (_loadViewerPromise) return _loadViewerPromise;
|
||||
|
||||
@@ -299,7 +299,7 @@ export default {
|
||||
|
||||
|
||||
// Register viewer resize handler
|
||||
context.ui().photoviewer.on('resize.openstreetcam', function(dimensions) {
|
||||
context.ui().photoviewer.on('resize.openstreetcam', function (dimensions) {
|
||||
imgZoom = d3_zoom()
|
||||
.extent([[0, 0], dimensions])
|
||||
.translateExtent([[0, 0], dimensions])
|
||||
@@ -316,7 +316,7 @@ export default {
|
||||
|
||||
|
||||
function rotate(deg) {
|
||||
return function() {
|
||||
return function () {
|
||||
if (!_oscSelectedImage) return;
|
||||
var sequenceKey = _oscSelectedImage.sequence_id;
|
||||
var sequence = _oscCache.sequences[sequenceKey];
|
||||
@@ -344,7 +344,7 @@ export default {
|
||||
}
|
||||
|
||||
function step(stepBy) {
|
||||
return function() {
|
||||
return function () {
|
||||
if (!_oscSelectedImage) return;
|
||||
var sequenceKey = _oscSelectedImage.sequence_id;
|
||||
var sequence = _oscCache.sequences[sequenceKey];
|
||||
@@ -368,7 +368,7 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
showViewer: function(context) {
|
||||
showViewer: function (context) {
|
||||
var viewer = context.container().select('.photoviewer')
|
||||
.classed('hide', false);
|
||||
|
||||
@@ -388,7 +388,7 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
hideViewer: function(context) {
|
||||
hideViewer: function (context) {
|
||||
_oscSelectedImage = null;
|
||||
|
||||
this.updateUrlImage(null);
|
||||
@@ -408,7 +408,7 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
selectImage: function(context, imageKey) {
|
||||
selectImage: function (context, imageKey) {
|
||||
|
||||
var d = this.cachedImage(imageKey);
|
||||
|
||||
@@ -494,12 +494,12 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
getSelectedImage: function() {
|
||||
getSelectedImage: function () {
|
||||
return _oscSelectedImage;
|
||||
},
|
||||
|
||||
|
||||
getSequenceKeyForImage: function(d) {
|
||||
getSequenceKeyForImage: function (d) {
|
||||
return d && d.sequence_id;
|
||||
},
|
||||
|
||||
@@ -507,7 +507,7 @@ export default {
|
||||
// Updates the currently highlighted sequence and selected bubble.
|
||||
// Reset is only necessary when interacting with the viewport because
|
||||
// this implicitly changes the currently selected bubble/sequence
|
||||
setStyles: function(context, hovered, reset) {
|
||||
setStyles: function (context, hovered, reset) {
|
||||
if (reset) { // reset all layers
|
||||
context.container().selectAll('.viewfield-group')
|
||||
.classed('highlighted', false)
|
||||
@@ -535,13 +535,13 @@ export default {
|
||||
var highlightedImageKeys = utilArrayUnion(hoveredImageKeys, selectedImageKeys);
|
||||
|
||||
context.container().selectAll('.layer-openstreetcam .viewfield-group')
|
||||
.classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
|
||||
.classed('hovered', function(d) { return d.key === hoveredImageKey; })
|
||||
.classed('currentView', function(d) { return d.key === selectedImageKey; });
|
||||
.classed('highlighted', function (d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
|
||||
.classed('hovered', function (d) { return d.key === hoveredImageKey; })
|
||||
.classed('currentView', function (d) { return d.key === selectedImageKey; });
|
||||
|
||||
context.container().selectAll('.layer-openstreetcam .sequence')
|
||||
.classed('highlighted', function(d) { return d.properties.key === hoveredSequenceKey; })
|
||||
.classed('currentView', function(d) { return d.properties.key === selectedSequenceKey; });
|
||||
.classed('highlighted', function (d) { return d.properties.key === hoveredSequenceKey; })
|
||||
.classed('currentView', function (d) { return d.properties.key === selectedSequenceKey; });
|
||||
|
||||
// update viewfields if needed
|
||||
context.container().selectAll('.layer-openstreetcam .viewfield-group .viewfield')
|
||||
@@ -560,7 +560,7 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
updateUrlImage: function(imageKey) {
|
||||
updateUrlImage: function (imageKey) {
|
||||
if (!window.mocha) {
|
||||
var hash = utilStringQs(window.location.hash);
|
||||
if (imageKey) {
|
||||
@@ -573,7 +573,7 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
cache: function() {
|
||||
cache: function () {
|
||||
return _oscCache;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@ import { actionChangeTags } from '../actions/change_tags';
|
||||
import { actionMergeNodes } from '../actions/merge_nodes';
|
||||
import { actionSplit } from '../actions/split';
|
||||
import { modeSelect } from '../modes/select';
|
||||
import { geoAngle, geoExtent, geoLatToMeters, geoLonToMeters, geoLineIntersection,
|
||||
geoSphericalClosestNode, geoSphericalDistance, geoVecAngle, geoVecLength, geoMetersToLat, geoMetersToLon } from '../geo';
|
||||
import {
|
||||
geoAngle, geoExtent, geoLatToMeters, geoLonToMeters, geoLineIntersection,
|
||||
geoSphericalClosestNode, geoSphericalDistance, geoVecAngle, geoVecLength, geoMetersToLat, geoMetersToLon
|
||||
} from '../geo';
|
||||
import { osmNode } from '../osm/node';
|
||||
import { osmFlowingWaterwayTagValues, osmPathHighwayTagValues, osmRailwayTrackTagValues, osmRoutableHighwayTagValues } from '../osm/tags';
|
||||
import { t } from '../core/localizer';
|
||||
@@ -312,7 +314,7 @@ export function validationCrossingWays(context) {
|
||||
if (entity.type === 'way') {
|
||||
return [entity];
|
||||
} else if (entity.type === 'relation') {
|
||||
return entity.members.reduce(function(array, member) {
|
||||
return entity.members.reduce(function (array, member) {
|
||||
if (member.type === 'way' &&
|
||||
// only look at geometry ways
|
||||
(!member.role || member.role === 'outer' || member.role === 'inner')) {
|
||||
@@ -351,7 +353,7 @@ export function validationCrossingWays(context) {
|
||||
function createIssue(crossing, graph) {
|
||||
|
||||
// use the entities with the tags that define the feature type
|
||||
crossing.wayInfos.sort(function(way1Info, way2Info) {
|
||||
crossing.wayInfos.sort(function (way1Info, way2Info) {
|
||||
var type1 = way1Info.featureType;
|
||||
var type2 = way2Info.featureType;
|
||||
if (type1 === type2) {
|
||||
@@ -363,7 +365,7 @@ export function validationCrossingWays(context) {
|
||||
}
|
||||
return type1 < type2;
|
||||
});
|
||||
var entities = crossing.wayInfos.map(function(wayInfo) {
|
||||
var entities = crossing.wayInfos.map(function (wayInfo) {
|
||||
return getFeatureWithFeatureTypeTagsForWay(wayInfo.way, graph);
|
||||
});
|
||||
var edges = [crossing.wayInfos[0].edge, crossing.wayInfos[1].edge];
|
||||
@@ -376,9 +378,9 @@ export function validationCrossingWays(context) {
|
||||
|
||||
var isCrossingIndoors = taggedAsIndoor(entities[0].tags) && taggedAsIndoor(entities[1].tags);
|
||||
var isCrossingTunnels = allowsTunnel(featureType1) && hasTag(entities[0].tags, 'tunnel') &&
|
||||
allowsTunnel(featureType2) && hasTag(entities[1].tags, 'tunnel');
|
||||
allowsTunnel(featureType2) && hasTag(entities[1].tags, 'tunnel');
|
||||
var isCrossingBridges = allowsBridge(featureType1) && hasTag(entities[0].tags, 'bridge') &&
|
||||
allowsBridge(featureType2) && hasTag(entities[1].tags, 'bridge');
|
||||
allowsBridge(featureType2) && hasTag(entities[1].tags, 'bridge');
|
||||
|
||||
var subtype = [featureType1, featureType2].sort().join('-');
|
||||
|
||||
@@ -396,13 +398,13 @@ export function validationCrossingWays(context) {
|
||||
}
|
||||
|
||||
// Differentiate based on the loc rounded to 4 digits, since two ways can cross multiple times.
|
||||
var uniqueID = '' + crossing.crossPoint[0].toFixed(4) + ',' + crossing.crossPoint[1].toFixed(4);
|
||||
var uniqueID = String(crossing.crossPoint[0].toFixed(4)) + ',' + String(crossing.crossPoint[1].toFixed(4));
|
||||
|
||||
return new validationIssue({
|
||||
type: type,
|
||||
subtype: subtype,
|
||||
severity: 'warning',
|
||||
message: function(context) {
|
||||
message: function (context) {
|
||||
var graph = context.graph();
|
||||
var entity1 = graph.hasEntity(this.entityIds[0]),
|
||||
entity2 = graph.hasEntity(this.entityIds[1]);
|
||||
@@ -412,7 +414,7 @@ export function validationCrossingWays(context) {
|
||||
}) : '';
|
||||
},
|
||||
reference: showReference,
|
||||
entityIds: entities.map(function(entity) {
|
||||
entityIds: entities.map(function (entity) {
|
||||
return entity.id;
|
||||
}),
|
||||
data: {
|
||||
@@ -422,7 +424,7 @@ export function validationCrossingWays(context) {
|
||||
},
|
||||
hash: uniqueID,
|
||||
loc: crossing.crossPoint,
|
||||
dynamicFixes: function(context) {
|
||||
dynamicFixes: function (context) {
|
||||
var mode = context.mode();
|
||||
if (!mode || mode.id !== 'select' || mode.selectedIDs().length !== 1) return [];
|
||||
|
||||
@@ -444,12 +446,12 @@ export function validationCrossingWays(context) {
|
||||
} else if (isCrossingTunnels ||
|
||||
isCrossingBridges ||
|
||||
featureType1 === 'building' ||
|
||||
featureType2 === 'building') {
|
||||
featureType2 === 'building') {
|
||||
|
||||
fixes.push(makeChangeLayerFix('higher'));
|
||||
fixes.push(makeChangeLayerFix('lower'));
|
||||
|
||||
// can only add bridge/tunnel if both features are lines
|
||||
// can only add bridge/tunnel if both features are lines
|
||||
} else if (context.graph().geometry(this.entityIds[0]) === 'line' &&
|
||||
context.graph().geometry(this.entityIds[1]) === 'line') {
|
||||
|
||||
@@ -485,11 +487,11 @@ export function validationCrossingWays(context) {
|
||||
}
|
||||
}
|
||||
|
||||
function makeAddBridgeOrTunnelFix(fixTitleID, iconName, bridgeOrTunnel){
|
||||
function makeAddBridgeOrTunnelFix(fixTitleID, iconName, bridgeOrTunnel) {
|
||||
return new validationIssueFix({
|
||||
icon: iconName,
|
||||
title: t.html('issues.fix.' + fixTitleID + '.title'),
|
||||
onClick: function(context) {
|
||||
onClick: function (context) {
|
||||
var mode = context.mode();
|
||||
if (!mode || mode.id !== 'select') return;
|
||||
|
||||
@@ -581,10 +583,10 @@ export function validationCrossingWays(context) {
|
||||
]);
|
||||
}
|
||||
|
||||
var endpointLocGetter1 = function(lengthMeters) {
|
||||
var endpointLocGetter1 = function (lengthMeters) {
|
||||
return locSphericalDistanceFromCrossingLoc(projectedAngle, lengthMeters);
|
||||
};
|
||||
var endpointLocGetter2 = function(lengthMeters) {
|
||||
var endpointLocGetter2 = function (lengthMeters) {
|
||||
return locSphericalDistanceFromCrossingLoc(projectedAngle + Math.PI, lengthMeters);
|
||||
};
|
||||
|
||||
@@ -612,8 +614,8 @@ export function validationCrossingWays(context) {
|
||||
|
||||
} else {
|
||||
var edgeCount = 0;
|
||||
endNode.parentIntersectionWays(graph).forEach(function(way) {
|
||||
way.nodes.forEach(function(nodeID) {
|
||||
endNode.parentIntersectionWays(graph).forEach(function (way) {
|
||||
way.nodes.forEach(function (nodeID) {
|
||||
if (nodeID === endNode.id) {
|
||||
if ((endNode.id === way.first() && endNode.id !== way.last()) ||
|
||||
(endNode.id === way.last() && endNode.id !== way.first())) {
|
||||
@@ -657,15 +659,15 @@ export function validationCrossingWays(context) {
|
||||
var structEndNode1 = determineEndpoint(edge, edgeNodes[1], endpointLocGetter1);
|
||||
var structEndNode2 = determineEndpoint([edgeNodes[0].id, structEndNode1.id], edgeNodes[0], endpointLocGetter2);
|
||||
|
||||
var structureWay = resultWayIDs.map(function(id) {
|
||||
var structureWay = resultWayIDs.map(function (id) {
|
||||
return graph.entity(id);
|
||||
}).find(function(way) {
|
||||
}).find(function (way) {
|
||||
return way.nodes.indexOf(structEndNode1.id) !== -1 &&
|
||||
way.nodes.indexOf(structEndNode2.id) !== -1;
|
||||
});
|
||||
|
||||
var tags = Object.assign({}, structureWay.tags); // copy tags
|
||||
if (bridgeOrTunnel === 'bridge'){
|
||||
if (bridgeOrTunnel === 'bridge') {
|
||||
tags.bridge = 'yes';
|
||||
tags.layer = '1';
|
||||
} else {
|
||||
@@ -698,7 +700,7 @@ export function validationCrossingWays(context) {
|
||||
return new validationIssueFix({
|
||||
icon: 'iD-icon-crossing',
|
||||
title: t.html('issues.fix.' + fixTitleID + '.title'),
|
||||
onClick: function(context) {
|
||||
onClick: function (context) {
|
||||
var loc = this.issue.loc;
|
||||
var connectionTags = this.issue.data.connectionTags;
|
||||
var edges = this.issue.data.edges;
|
||||
@@ -712,16 +714,16 @@ export function validationCrossingWays(context) {
|
||||
var nodesToMerge = [node.id];
|
||||
var mergeThresholdInMeters = 0.75;
|
||||
|
||||
edges.forEach(function(edge) {
|
||||
edges.forEach(function (edge) {
|
||||
var edgeNodes = [graph.entity(edge[0]), graph.entity(edge[1])];
|
||||
var nearby = geoSphericalClosestNode(edgeNodes, loc);
|
||||
// if there is already a suitable node nearby, use that
|
||||
// use the node if node has no interesting tags or if it is a crossing node #8326
|
||||
if ((!nearby.node.hasInterestingTags() || nearby.node.isCrossing()) && nearby.distance < mergeThresholdInMeters) {
|
||||
nodesToMerge.push(nearby.node.id);
|
||||
// else add the new node to the way
|
||||
// else add the new node to the way
|
||||
} else {
|
||||
graph = actionAddMidpoint({loc: loc, edge: edge}, node)(graph);
|
||||
graph = actionAddMidpoint({ loc: loc, edge: edge }, node)(graph);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -742,7 +744,7 @@ export function validationCrossingWays(context) {
|
||||
return new validationIssueFix({
|
||||
icon: 'iD-icon-' + (higherOrLower === 'higher' ? 'up' : 'down'),
|
||||
title: t.html('issues.fix.tag_this_as_' + higherOrLower + '.title'),
|
||||
onClick: function(context) {
|
||||
onClick: function (context) {
|
||||
|
||||
var mode = context.mode();
|
||||
if (!mode || mode.id !== 'select') return;
|
||||
@@ -751,7 +753,7 @@ export function validationCrossingWays(context) {
|
||||
if (selectedIDs.length !== 1) return;
|
||||
|
||||
var selectedID = selectedIDs[0];
|
||||
if (!this.issue.entityIds.some(function(entityId) {
|
||||
if (!this.issue.entityIds.some(function (entityId) {
|
||||
return entityId === selectedID;
|
||||
})) return;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"quickstart": "npm-run-all -s build:dev start:server",
|
||||
"start:server": "node scripts/server.js",
|
||||
"test": "npm-run-all -s lint build:css build:data build:legacy test:spec",
|
||||
"test:spec": "karma start my.conf.js",
|
||||
"test:spec": "karma start karma.conf.js",
|
||||
"translations": "node scripts/update_locales.js"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -133,4 +133,4 @@
|
||||
"browserslist": [
|
||||
"> 0.2%, last 6 major versions, Firefox ESR, IE 11, maintained node versions"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
describe.only('iD.behaviorSelect', function () {
|
||||
describe('iD.behaviorSelect', function () {
|
||||
var a, b, context, behavior, container;
|
||||
|
||||
function simulateClick(el, o) {
|
||||
@@ -10,7 +10,7 @@ describe.only('iD.behaviorSelect', function () {
|
||||
happen.mouseup(el, Object.assign({}, click, o));
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
container = d3.select('body').append('div');
|
||||
context = iD.coreContext().assetPath('../dist/').init().container(container);
|
||||
|
||||
@@ -43,72 +43,72 @@ describe.only('iD.behaviorSelect', function () {
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it('refuses to enter select mode with no ids', function() {
|
||||
it('refuses to enter select mode with no ids', function () {
|
||||
context.enter(iD.modeSelect(context, []));
|
||||
expect(context.mode().id, 'empty array').to.eql('browse');
|
||||
context.enter(iD.modeSelect(context, undefined));
|
||||
expect(context.mode().id, 'undefined').to.eql('browse');
|
||||
});
|
||||
|
||||
it('refuses to enter select mode with nonexistent ids', function() {
|
||||
it('refuses to enter select mode with nonexistent ids', function () {
|
||||
context.enter(iD.modeSelect(context, ['w-1']));
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
});
|
||||
|
||||
it('click on entity selects the entity', function(done) {
|
||||
it('click on entity selects the entity', function (done) {
|
||||
var el = context.surface().selectAll('.' + a.id).node();
|
||||
simulateClick(el, {});
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
it('click on empty space clears the selection', function(done) {
|
||||
it('click on empty space clears the selection', function (done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().node();
|
||||
simulateClick(el, {});
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
it('shift-click on unselected entity adds it to the selection', function(done) {
|
||||
it('shift-click on unselected entity adds it to the selection', function (done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().selectAll('.' + b.id).node();
|
||||
simulateClick(el, { shiftKey: true });
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.selectedIDs()).to.eql([a.id, b.id]);
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
it('shift-click on selected entity removes it from the selection', function(done) {
|
||||
it('shift-click on selected entity removes it from the selection', function (done) {
|
||||
context.enter(iD.modeSelect(context, [a.id, b.id]));
|
||||
var el = context.surface().selectAll('.' + b.id).node();
|
||||
simulateClick(el, { shiftKey: true });
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
it('shift-click on last selected entity clears the selection', function(done) {
|
||||
it('shift-click on last selected entity clears the selection', function (done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().selectAll('.' + a.id).node();
|
||||
simulateClick(el, { shiftKey: true });
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
it('shift-click on empty space leaves the selection unchanged', function(done) {
|
||||
it('shift-click on empty space leaves the selection unchanged', function (done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().node();
|
||||
simulateClick(el, { shiftKey: true });
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
done();
|
||||
}, 50);
|
||||
|
||||
@@ -1,127 +1,127 @@
|
||||
describe('iD.coreLocations', function() {
|
||||
describe('iD.coreLocations', function () {
|
||||
var locationManager, loco;
|
||||
|
||||
var colorado = {
|
||||
type: 'Feature',
|
||||
id: 'colorado.geojson',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[-107.9197, 41.0039],
|
||||
[-102.0539, 41.0039],
|
||||
[-102.043, 36.9948],
|
||||
[-109.0425, 37.0003],
|
||||
[-109.048, 40.9984],
|
||||
[-107.9197, 41.0039]
|
||||
]
|
||||
]
|
||||
}
|
||||
type: 'Feature',
|
||||
id: 'colorado.geojson',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[-107.9197, 41.0039],
|
||||
[-102.0539, 41.0039],
|
||||
[-102.043, 36.9948],
|
||||
[-109.0425, 37.0003],
|
||||
[-109.048, 40.9984],
|
||||
[-107.9197, 41.0039]
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
var fc = { type: 'FeatureCollection', features: [colorado] };
|
||||
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
// make a new one each time, so we aren't accidentally testing the "global" locationManager
|
||||
locationManager = iD.coreLocations();
|
||||
loco = locationManager.loco();
|
||||
});
|
||||
|
||||
|
||||
describe('#mergeCustomGeoJSON', function() {
|
||||
it('merges geojson into lococation-conflation cache', function() {
|
||||
describe('#mergeCustomGeoJSON', function () {
|
||||
it('merges geojson into lococation-conflation cache', function () {
|
||||
locationManager.mergeCustomGeoJSON(fc);
|
||||
expect(loco._cache['colorado.geojson']).to.be.eql(colorado);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#mergeLocationSets', function() {
|
||||
it('returns a promise rejected if not passed an array', function(done) {
|
||||
describe('#mergeLocationSets', function () {
|
||||
it('returns a promise rejected if not passed an array', function (done) {
|
||||
var prom = locationManager.mergeLocationSets({});
|
||||
prom
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
done(new Error('This was supposed to fail, but somehow succeeded.'));
|
||||
})
|
||||
.catch(function(err) {
|
||||
.catch(function (err) {
|
||||
expect(/^nothing to do/.test(err)).to.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
window.setTimeout(function() {}, 20); // async - to let the promise settle in phantomjs
|
||||
window.setTimeout(function () { }, 20); // async - to let the promise settle in phantomjs
|
||||
});
|
||||
|
||||
it('resolves locationSets, assigning locationSetID', function(done) {
|
||||
it('resolves locationSets, assigning locationSetID', function (done) {
|
||||
var data = [
|
||||
{ id: 'world', locationSet: { include: ['001'] } },
|
||||
{ id: 'usa', locationSet: { include: ['usa'] } }
|
||||
{ id: 'usa', locationSet: { include: ['usa'] } }
|
||||
];
|
||||
var prom = locationManager.mergeLocationSets(data);
|
||||
prom
|
||||
.then(function(data) {
|
||||
.then(function (data) {
|
||||
expect(data).to.be.a('array');
|
||||
expect(data[0].locationSetID).to.eql('+[Q2]');
|
||||
expect(data[1].locationSetID).to.eql('+[Q30]');
|
||||
done();
|
||||
})
|
||||
.catch(function(err) {
|
||||
.catch(function (err) {
|
||||
done(err);
|
||||
});
|
||||
|
||||
window.setTimeout(function() {}, 20); // async - to let the promise settle in phantomjs
|
||||
window.setTimeout(function () { }, 20); // async - to let the promise settle in phantomjs
|
||||
});
|
||||
|
||||
it('resolves locationSets, falls back to world locationSetID on errror', function(done) {
|
||||
it('resolves locationSets, falls back to world locationSetID on errror', function (done) {
|
||||
var data = [
|
||||
{ id: 'bogus1', locationSet: { foo: 'bar' } },
|
||||
{ id: 'bogus2', locationSet: { include: ['fake.geojson'] } }
|
||||
];
|
||||
var prom = locationManager.mergeLocationSets(data);
|
||||
prom
|
||||
.then(function(data) {
|
||||
.then(function (data) {
|
||||
expect(data).to.be.a('array');
|
||||
expect(data[0].locationSetID).to.eql('+[Q2]');
|
||||
expect(data[1].locationSetID).to.eql('+[Q2]');
|
||||
done();
|
||||
})
|
||||
.catch(function(err) {
|
||||
.catch(function (err) {
|
||||
done(err);
|
||||
});
|
||||
|
||||
window.setTimeout(function() {}, 20); // async - to let the promise settle in phantomjs
|
||||
window.setTimeout(function () { }, 20); // async - to let the promise settle in phantomjs
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#locationSetID', function() {
|
||||
it('calculates a locationSetID for a locationSet', function() {
|
||||
describe('#locationSetID', function () {
|
||||
it('calculates a locationSetID for a locationSet', function () {
|
||||
expect(locationManager.locationSetID({ include: ['usa'] })).to.be.eql('+[Q30]');
|
||||
});
|
||||
|
||||
it('falls back to the world locationSetID in case of errors', function() {
|
||||
it('falls back to the world locationSetID in case of errors', function () {
|
||||
expect(locationManager.locationSetID({ foo: 'bar' })).to.be.eql('+[Q2]');
|
||||
expect(locationManager.locationSetID({ include: ['fake.geojson'] })).to.be.eql('+[Q2]');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#feature', function() {
|
||||
it('has the world locationSet pre-resolved', function() {
|
||||
describe('#feature', function () {
|
||||
it('has the world locationSet pre-resolved', function () {
|
||||
var result = locationManager.feature('+[Q2]');
|
||||
expect(result).to.include({ type: 'Feature', id: '+[Q2]' });
|
||||
});
|
||||
|
||||
it('falls back to the world locationSetID in case of errors', function() {
|
||||
it('falls back to the world locationSetID in case of errors', function () {
|
||||
var result = locationManager.feature('fake');
|
||||
expect(result).to.include({ type: 'Feature', id: '+[Q2]' });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#locationsAt', function() {
|
||||
it('has the world locationSet pre-resolved', function() {
|
||||
describe('#locationsAt', function () {
|
||||
it('has the world locationSet pre-resolved', function () {
|
||||
var result1 = locationManager.locationsAt([-108.557, 39.065]); // Grand Junction
|
||||
expect(result1).to.be.an('object').that.has.all.keys('+[Q2]');
|
||||
var result2 = locationManager.locationsAt([-74.481, 40.797]); // Morristown
|
||||
@@ -130,7 +130,7 @@ describe('iD.coreLocations', function() {
|
||||
expect(result3).to.be.an('object').that.has.all.keys('+[Q2]');
|
||||
});
|
||||
|
||||
it('returns valid locations at a given lon,lat', function(done) {
|
||||
it('returns valid locations at a given lon,lat', function (done) {
|
||||
// setup, load colorado.geojson and resolve some locationSets
|
||||
locationManager.mergeCustomGeoJSON(fc);
|
||||
locationManager.mergeLocationSets([
|
||||
@@ -138,7 +138,7 @@ describe('iD.coreLocations', function() {
|
||||
{ id: 'OSM-USA', locationSet: { include: ['us'] } },
|
||||
{ id: 'OSM-Colorado', locationSet: { include: ['colorado.geojson'] } }
|
||||
])
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
var result1 = locationManager.locationsAt([-108.557, 39.065]); // Grand Junction
|
||||
expect(result1).to.be.an('object').that.has.all.keys('+[Q2]', '+[Q30]', '+[colorado.geojson]');
|
||||
var result2 = locationManager.locationsAt([-74.481, 40.797]); // Morristown
|
||||
@@ -147,11 +147,11 @@ describe('iD.coreLocations', function() {
|
||||
expect(result3).to.be.an('object').that.has.all.keys('+[Q2]');
|
||||
done();
|
||||
})
|
||||
.catch(function(err) {
|
||||
.catch(function (err) {
|
||||
done(err);
|
||||
});
|
||||
|
||||
window.setTimeout(function() {}, 20); // async - to let the promise settle in phantomjs
|
||||
window.setTimeout(function () { }, 20); // async - to let the promise settle in phantomjs
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
describe('maprules', function() {
|
||||
describe('maprules', function () {
|
||||
var _ruleChecks, _savedAreaKeys, validationRules;
|
||||
|
||||
before(function() {
|
||||
before(function () {
|
||||
_savedAreaKeys = iD.osmAreaKeys;
|
||||
iD.osmSetAreaKeys({ building: {}, amenity: {} });
|
||||
|
||||
@@ -10,16 +10,16 @@ describe('maprules', function() {
|
||||
_ruleChecks = iD.serviceMapRules.ruleChecks();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
after(function () {
|
||||
iD.osmSetAreaKeys(_savedAreaKeys);
|
||||
delete iD.services.maprules;
|
||||
});
|
||||
|
||||
describe('#filterRuleChecks', function() {
|
||||
it('returns shortlist of mapcss checks relevant to provided selector', function() {
|
||||
describe('#filterRuleChecks', function () {
|
||||
it('returns shortlist of mapcss checks relevant to provided selector', function () {
|
||||
var selector = {
|
||||
geometry: 'closedway',
|
||||
equals: {amenity: 'marketplace'},
|
||||
equals: { amenity: 'marketplace' },
|
||||
absence: 'name',
|
||||
error: '\'Marketplace\' preset must be coupled with name'
|
||||
};
|
||||
@@ -34,8 +34,8 @@ describe('maprules', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#buildTagMap', function() {
|
||||
it('builds a map of tag keys/values found in mapcss selector', function() {
|
||||
describe('#buildTagMap', function () {
|
||||
it('builds a map of tag keys/values found in mapcss selector', function () {
|
||||
[
|
||||
{
|
||||
t: {
|
||||
@@ -90,14 +90,14 @@ describe('maprules', function() {
|
||||
lanes: [4, 1]
|
||||
}
|
||||
}
|
||||
].forEach(function(test) {
|
||||
].forEach(function (test) {
|
||||
expect(iD.serviceMapRules.buildTagMap(test.t)).to.eql(test.r);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#inferGeometry', function() {
|
||||
it('infers geometry using selector keys', function() {
|
||||
describe('#inferGeometry', function () {
|
||||
it('infers geometry using selector keys', function () {
|
||||
|
||||
var amenityDerivedArea = {
|
||||
geometry: 'closedway',
|
||||
@@ -148,32 +148,32 @@ describe('maprules', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#addRule', function() {
|
||||
describe('#addRule', function () {
|
||||
it('builds a rule from provided selector and adds it to _validationRules', function () {
|
||||
var selector = {
|
||||
geometry:'node',
|
||||
equals: {amenity:'marketplace'},
|
||||
absence:'name',
|
||||
warning:'\'Marketplace\' preset must be coupled with name'
|
||||
geometry: 'node',
|
||||
equals: { amenity: 'marketplace' },
|
||||
absence: 'name',
|
||||
warning: '\'Marketplace\' preset must be coupled with name'
|
||||
};
|
||||
expect(iD.serviceMapRules.validationRules()).to.be.empty;
|
||||
iD.serviceMapRules.addRule(selector);
|
||||
expect(iD.serviceMapRules.validationRules().length).to.eql(1);
|
||||
});
|
||||
});
|
||||
describe('#clearRules', function() {
|
||||
it('clears _validationRules array', function() {
|
||||
describe('#clearRules', function () {
|
||||
it('clears _validationRules array', function () {
|
||||
expect(iD.serviceMapRules.validationRules().length).to.eql(1);
|
||||
iD.serviceMapRules.clearRules();
|
||||
expect(iD.serviceMapRules.validationRules()).to.be.empty;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#validationRules', function() {
|
||||
it('returns _validationRules array', function() {
|
||||
describe('#validationRules', function () {
|
||||
it('returns _validationRules array', function () {
|
||||
var selector = {
|
||||
geometry: 'closedway',
|
||||
equals: {amenity: 'marketplace'},
|
||||
equals: { amenity: 'marketplace' },
|
||||
absence: 'name',
|
||||
error: '\'Marketplace\' preset must be coupled with name'
|
||||
};
|
||||
@@ -185,71 +185,71 @@ describe('maprules', function() {
|
||||
});
|
||||
|
||||
describe('_ruleChecks', function () {
|
||||
describe('#equals', function() {
|
||||
it('is true when two tag maps intersect', function() {
|
||||
describe('#equals', function () {
|
||||
it('is true when two tag maps intersect', function () {
|
||||
var a = { amenity: 'school' };
|
||||
var b = { amenity: 'school' };
|
||||
expect(_ruleChecks.equals(a)(b)).to.be.true;
|
||||
});
|
||||
it('is false when two tag maps intersect', function() {
|
||||
it('is false when two tag maps intersect', function () {
|
||||
var a = { man_made: 'water_tap' };
|
||||
var b = { amenity: 'school' };
|
||||
expect(_ruleChecks.equals(a)(b)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('#notEquals', function() {
|
||||
it('is true when two tag maps do not intersect', function() {
|
||||
describe('#notEquals', function () {
|
||||
it('is true when two tag maps do not intersect', function () {
|
||||
var a = { man_made: 'water_tap' };
|
||||
var b = { amenity: 'school' };
|
||||
expect(_ruleChecks.notEquals(a)(b)).to.be.true;
|
||||
});
|
||||
it('is not true when two tag maps intersect', function() {
|
||||
it('is not true when two tag maps intersect', function () {
|
||||
var a = { amenity: 'school' };
|
||||
var b = { amenity: 'school', opening_hours: '9-5' };
|
||||
expect(_ruleChecks.notEquals(a)(b)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('absence', function() {
|
||||
it('is true when tag map keys does not include key in question', function() {
|
||||
describe('absence', function () {
|
||||
it('is true when tag map keys does not include key in question', function () {
|
||||
var key = 'amenity';
|
||||
var map = { building: 'yes' };
|
||||
expect(_ruleChecks.absence(key)(map)).to.be.true;
|
||||
});
|
||||
it('is false when tag map keys does include key in question', function() {
|
||||
it('is false when tag map keys does include key in question', function () {
|
||||
var key = 'amenity';
|
||||
var map = { amenity: 'school' };
|
||||
expect(_ruleChecks.absence(key)(map)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('presence', function() {
|
||||
it('is true when tag map keys includes key in question', function() {
|
||||
describe('presence', function () {
|
||||
it('is true when tag map keys includes key in question', function () {
|
||||
var key = 'amenity';
|
||||
var map = { amenity: 'school'};
|
||||
var map = { amenity: 'school' };
|
||||
expect(_ruleChecks.presence(key)(map)).to.be.true;
|
||||
});
|
||||
it('is false when tag map keys do not include key in question', function() {
|
||||
it('is false when tag map keys do not include key in question', function () {
|
||||
var key = 'amenity';
|
||||
var map = { building: 'yes'};
|
||||
var map = { building: 'yes' };
|
||||
expect(_ruleChecks.presence(key)(map)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('greaterThan', function() {
|
||||
it('is true when a tag value is greater than the selector value', function() {
|
||||
describe('greaterThan', function () {
|
||||
it('is true when a tag value is greater than the selector value', function () {
|
||||
var selectorTags = { lanes: 5 };
|
||||
var tags = { lanes : 6 };
|
||||
var tags = { lanes: 6 };
|
||||
expect(_ruleChecks.greaterThan(selectorTags)(tags)).to.be.true;
|
||||
});
|
||||
it('is false when a tag value is less than or equal to the selector value', function() {
|
||||
it('is false when a tag value is less than or equal to the selector value', function () {
|
||||
var selectorTags = { lanes: 5 };
|
||||
[4, 5].forEach(function(val) {
|
||||
[4, 5].forEach(function (val) {
|
||||
expect(_ruleChecks.greaterThan(selectorTags)({ lanes: val })).to.be.false;
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('greaterThanEqual', function() {
|
||||
it('is true when a tag value is greater than or equal to the selector value', function() {
|
||||
describe('greaterThanEqual', function () {
|
||||
it('is true when a tag value is greater than or equal to the selector value', function () {
|
||||
var selectorTags = { lanes: 5 };
|
||||
[5, 6].forEach(function(val) {
|
||||
[5, 6].forEach(function (val) {
|
||||
expect(_ruleChecks.greaterThanEqual(selectorTags)({ lanes: val })).to.be.true;
|
||||
});
|
||||
});
|
||||
@@ -259,64 +259,64 @@ describe('maprules', function() {
|
||||
expect(_ruleChecks.greaterThanEqual(selectorTags)(tags)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('lessThan', function() {
|
||||
it('is true when a tag value is less than the selector value', function() {
|
||||
describe('lessThan', function () {
|
||||
it('is true when a tag value is less than the selector value', function () {
|
||||
var selectorTags = { lanes: 5 };
|
||||
var tags = { lanes: 4 };
|
||||
expect(_ruleChecks.lessThan(selectorTags)(tags)).to.be.true;
|
||||
});
|
||||
it('is false when a tag value is greater than or equal to the selector value', function() {
|
||||
it('is false when a tag value is greater than or equal to the selector value', function () {
|
||||
var selectorTags = { lanes: 5 };
|
||||
[6, 7].forEach(function(val) {
|
||||
expect(_ruleChecks.lessThan(selectorTags)({ lanes: val })).to.be.false;
|
||||
});
|
||||
[6, 7].forEach(function (val) {
|
||||
expect(_ruleChecks.lessThan(selectorTags)({ lanes: val })).to.be.false;
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('lessThanEqual', function() {
|
||||
it('is true when a tag value is less than or equal to the selector value', function() {
|
||||
describe('lessThanEqual', function () {
|
||||
it('is true when a tag value is less than or equal to the selector value', function () {
|
||||
var selectorTags = { lanes: 5 };
|
||||
[4, 5].forEach(function(val) {
|
||||
[4, 5].forEach(function (val) {
|
||||
expect(_ruleChecks.lessThanEqual(selectorTags)({ lanes: val })).to.be.true;
|
||||
});
|
||||
});
|
||||
it('is false when a tag value is greater than the selector value', function() {
|
||||
var selectorTags = { lanes: 5 };
|
||||
var tags = { lanes: 6 };
|
||||
expect(_ruleChecks.lessThanEqual(selectorTags)(tags)).to.be.false;
|
||||
it('is false when a tag value is greater than the selector value', function () {
|
||||
var selectorTags = { lanes: 5 };
|
||||
var tags = { lanes: 6 };
|
||||
expect(_ruleChecks.lessThanEqual(selectorTags)(tags)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('positiveRegex', function() {
|
||||
var positiveRegex = { amenity: ['^hospital$','^clinic$']};
|
||||
it('is true when tag value matches positiveRegex', function() {
|
||||
describe('positiveRegex', function () {
|
||||
var positiveRegex = { amenity: ['^hospital$', '^clinic$'] };
|
||||
it('is true when tag value matches positiveRegex', function () {
|
||||
var tags = { amenity: 'hospital' };
|
||||
expect(_ruleChecks.positiveRegex(positiveRegex)(tags)).to.be.true;
|
||||
});
|
||||
it('is false when tag value does not match negative regex', function() {
|
||||
it('is false when tag value does not match negative regex', function () {
|
||||
var tags = { amenity: 'school' };
|
||||
expect(_ruleChecks.positiveRegex(positiveRegex)(tags)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('negativeRegex', function() {
|
||||
var negativeRegex = { bicycle: [ 'use_path', 'designated' ] };
|
||||
it('is true when tag value does not match negativeRegex', function() {
|
||||
describe('negativeRegex', function () {
|
||||
var negativeRegex = { bicycle: ['use_path', 'designated'] };
|
||||
it('is true when tag value does not match negativeRegex', function () {
|
||||
var tags = { bicycle: 'yes' };
|
||||
expect(_ruleChecks.negativeRegex(negativeRegex)(tags)).to.be.true;
|
||||
});
|
||||
it('is false when tag value matches negativeRegex', function() {
|
||||
it('is false when tag value matches negativeRegex', function () {
|
||||
var tags = { bicycle: 'designated' };
|
||||
expect(_ruleChecks.negativeRegex(negativeRegex)(tags)).to.be.false;
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('rule', function() {
|
||||
describe('rule', function () {
|
||||
var selectors;
|
||||
before(function() {
|
||||
before(function () {
|
||||
selectors = [
|
||||
{
|
||||
geometry:'node',
|
||||
equals: {amenity:'marketplace'},
|
||||
absence:'name',
|
||||
error:'\'Marketplace\' preset must be coupled with name'
|
||||
geometry: 'node',
|
||||
equals: { amenity: 'marketplace' },
|
||||
absence: 'name',
|
||||
error: '\'Marketplace\' preset must be coupled with name'
|
||||
},
|
||||
{
|
||||
geometry: 'closedway',
|
||||
@@ -324,10 +324,10 @@ describe('maprules', function() {
|
||||
error: '\'Clinic\' preset must be coupled with building=yes'
|
||||
},
|
||||
{
|
||||
geometry:'node',
|
||||
equals: {man_made: 'tower', 'tower:type': 'communication'},
|
||||
geometry: 'node',
|
||||
equals: { man_made: 'tower', 'tower:type': 'communication' },
|
||||
presence: 'height',
|
||||
error:'\'Communication Tower\' preset must not be coupled with height'
|
||||
error: '\'Communication Tower\' preset must not be coupled with height'
|
||||
},
|
||||
{
|
||||
geometry: 'node',
|
||||
@@ -368,18 +368,18 @@ describe('maprules', function() {
|
||||
];
|
||||
|
||||
iD.serviceMapRules.clearRules();
|
||||
selectors.forEach(function(selector) { iD.serviceMapRules.addRule(selector); });
|
||||
selectors.forEach(function (selector) { iD.serviceMapRules.addRule(selector); });
|
||||
validationRules = iD.serviceMapRules.validationRules();
|
||||
});
|
||||
describe('#matches', function() {
|
||||
describe('#matches', function () {
|
||||
var selectors, entities;
|
||||
before(function() {
|
||||
before(function () {
|
||||
selectors = [
|
||||
{
|
||||
geometry:'node',
|
||||
equals: {amenity:'marketplace'},
|
||||
absence:'name',
|
||||
error:'\'Marketplace\' preset must be coupled with name'
|
||||
geometry: 'node',
|
||||
equals: { amenity: 'marketplace' },
|
||||
absence: 'name',
|
||||
error: '\'Marketplace\' preset must be coupled with name'
|
||||
},
|
||||
{
|
||||
geometry: 'closedway',
|
||||
@@ -387,10 +387,10 @@ describe('maprules', function() {
|
||||
error: '\'Clinic\' preset must be coupled with building=yes'
|
||||
},
|
||||
{
|
||||
geometry:'node',
|
||||
equals: {man_made: 'tower', 'tower:type': 'communication'},
|
||||
geometry: 'node',
|
||||
equals: { man_made: 'tower', 'tower:type': 'communication' },
|
||||
presence: 'height',
|
||||
error:'\'Communication Tower\' preset must not be coupled with height'
|
||||
error: '\'Communication Tower\' preset must not be coupled with height'
|
||||
},
|
||||
{
|
||||
geometry: 'node',
|
||||
@@ -430,34 +430,34 @@ describe('maprules', function() {
|
||||
}
|
||||
];
|
||||
entities = [
|
||||
iD.osmEntity({ type: 'node', tags: { amenity: 'marketplace' }}),
|
||||
iD.osmWay({ tags: { building: 'house', amenity: 'clinic' }, nodes: [ 'a', 'b', 'c', 'a' ]}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', 'tower:type': 'communication', height: 5 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 6 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 9 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 5 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 10 }}),
|
||||
iD.osmWay({ tags: { amenity: 'clinic', emergency: 'definitely' }, nodes: [ 'd', 'e', 'f', 'd' ]}),
|
||||
iD.osmWay({ tags: { highway: 'residential', structure: 'bridge' }}),
|
||||
iD.osmEntity({ type: 'node', tags: { amenity: 'marketplace' } }),
|
||||
iD.osmWay({ tags: { building: 'house', amenity: 'clinic' }, nodes: ['a', 'b', 'c', 'a'] }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', 'tower:type': 'communication', height: 5 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 6 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 9 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 5 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 10 } }),
|
||||
iD.osmWay({ tags: { amenity: 'clinic', emergency: 'definitely' }, nodes: ['d', 'e', 'f', 'd'] }),
|
||||
iD.osmWay({ tags: { highway: 'residential', structure: 'bridge' } }),
|
||||
];
|
||||
|
||||
iD.serviceMapRules.clearRules();
|
||||
selectors.forEach(function(selector) { iD.serviceMapRules.addRule(selector); });
|
||||
selectors.forEach(function (selector) { iD.serviceMapRules.addRule(selector); });
|
||||
validationRules = iD.serviceMapRules.validationRules();
|
||||
});
|
||||
it('is true when each rule check is \'true\'', function() {
|
||||
validationRules.forEach(function(rule, i) {
|
||||
it('is true when each rule check is \'true\'', function () {
|
||||
validationRules.forEach(function (rule, i) {
|
||||
expect(rule.matches(entities[i])).to.be.true;
|
||||
});
|
||||
});
|
||||
it('is true when at least one rule check is \'false\'', function() {
|
||||
it('is true when at least one rule check is \'false\'', function () {
|
||||
var selector = {
|
||||
geometry: 'way',
|
||||
equals: { highway: 'residential' },
|
||||
positiveRegex: { structure: ['embarkment', 'bridge'] },
|
||||
error: '\'suburban road\' structure tag cannot be \'bridge\' or \'tunnel\''
|
||||
};
|
||||
var entity = iD.osmWay({ tags: { highway: 'residential', structure: 'tunnel' }});
|
||||
var entity = iD.osmWay({ tags: { highway: 'residential', structure: 'tunnel' } });
|
||||
iD.serviceMapRules.clearRules();
|
||||
iD.serviceMapRules.addRule(selector);
|
||||
var rule = iD.serviceMapRules.validationRules()[0];
|
||||
@@ -465,16 +465,16 @@ describe('maprules', function() {
|
||||
expect(rule.matches(entity)).to.be.false;
|
||||
});
|
||||
});
|
||||
describe('#findIssues', function() {
|
||||
describe('#findIssues', function () {
|
||||
var selectors, entities, _graph;
|
||||
|
||||
before(function() {
|
||||
before(function () {
|
||||
selectors = [
|
||||
{
|
||||
geometry:'node',
|
||||
equals: {amenity:'marketplace'},
|
||||
absence:'name',
|
||||
error:'\'Marketplace\' preset must be coupled with name'
|
||||
geometry: 'node',
|
||||
equals: { amenity: 'marketplace' },
|
||||
absence: 'name',
|
||||
error: '\'Marketplace\' preset must be coupled with name'
|
||||
},
|
||||
{
|
||||
geometry: 'closedway',
|
||||
@@ -482,10 +482,10 @@ describe('maprules', function() {
|
||||
error: '\'Clinic\' preset must be coupled with building=yes'
|
||||
},
|
||||
{
|
||||
geometry:'node',
|
||||
equals: {man_made: 'tower', 'tower:type': 'communication'},
|
||||
geometry: 'node',
|
||||
equals: { man_made: 'tower', 'tower:type': 'communication' },
|
||||
presence: 'height',
|
||||
error:'\'Communication Tower\' preset must not be coupled with height'
|
||||
error: '\'Communication Tower\' preset must not be coupled with height'
|
||||
},
|
||||
{
|
||||
geometry: 'node',
|
||||
@@ -525,15 +525,15 @@ describe('maprules', function() {
|
||||
}
|
||||
];
|
||||
entities = [
|
||||
iD.osmEntity({ type: 'node', tags: { amenity: 'marketplace' }}),
|
||||
iD.osmWay({ tags: { building: 'house', amenity: 'clinic' }, nodes: [ 'a', 'b', 'c', 'a' ]}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', 'tower:type': 'communication', height: 5 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 6 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 9 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 5 }}),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 10 }}),
|
||||
iD.osmWay({ tags: { amenity: 'clinic', emergency: 'definitely' }, nodes: [ 'd', 'e', 'f', 'd' ]}),
|
||||
iD.osmWay({ tags: { highway: 'residential', structure: 'bridge' }}),
|
||||
iD.osmEntity({ type: 'node', tags: { amenity: 'marketplace' } }),
|
||||
iD.osmWay({ tags: { building: 'house', amenity: 'clinic' }, nodes: ['a', 'b', 'c', 'a'] }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', 'tower:type': 'communication', height: 5 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 6 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 9 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 5 } }),
|
||||
iD.osmEntity({ type: 'node', tags: { man_made: 'tower', height: 10 } }),
|
||||
iD.osmWay({ tags: { amenity: 'clinic', emergency: 'definitely' }, nodes: ['d', 'e', 'f', 'd'] }),
|
||||
iD.osmWay({ tags: { highway: 'residential', structure: 'bridge' } }),
|
||||
];
|
||||
|
||||
var wayNodes = [
|
||||
@@ -546,11 +546,11 @@ describe('maprules', function() {
|
||||
];
|
||||
_graph = iD.coreGraph(entities.concat(wayNodes));
|
||||
iD.serviceMapRules.clearRules();
|
||||
selectors.forEach(function(selector) { iD.serviceMapRules.addRule(selector); });
|
||||
selectors.forEach(function (selector) { iD.serviceMapRules.addRule(selector); });
|
||||
validationRules = iD.serviceMapRules.validationRules();
|
||||
});
|
||||
it('finds issues', function() {
|
||||
validationRules.forEach(function(rule, i) {
|
||||
it('finds issues', function () {
|
||||
validationRules.forEach(function (rule, i) {
|
||||
var issues = [];
|
||||
var entity = entities[i];
|
||||
var selector = selectors[i];
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
describe('iD.serviceOpenstreetcam', function() {
|
||||
describe('iD.serviceOpenstreetcam', function () {
|
||||
var dimensions = [64, 64];
|
||||
var context, server, openstreetcam;
|
||||
var context, openstreetcam;
|
||||
|
||||
before(function() {
|
||||
before(function () {
|
||||
iD.services.openstreetcam = iD.serviceOpenstreetcam;
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
after(function () {
|
||||
delete iD.services.openstreetcam;
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
context = iD.coreContext().assetPath('../dist/').init();
|
||||
context.projection
|
||||
.scale(iD.geoZoomToScale(14))
|
||||
.translate([-116508, 0]) // 10,0
|
||||
.clipExtent([[0,0], dimensions]);
|
||||
.clipExtent([[0, 0], dimensions]);
|
||||
|
||||
server = window.fakeFetch().create();
|
||||
openstreetcam = iD.services.openstreetcam;
|
||||
openstreetcam.reset();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
afterEach(function () {
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
|
||||
describe('#init', function() {
|
||||
it('Initializes cache one time', function() {
|
||||
describe('#init', function () {
|
||||
it('Initializes cache one time', function () {
|
||||
var cache = openstreetcam.cache();
|
||||
expect(cache).to.have.property('images');
|
||||
expect(cache).to.have.property('sequences');
|
||||
@@ -39,10 +40,10 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#reset', function() {
|
||||
it('resets cache and image', function() {
|
||||
describe('#reset', function () {
|
||||
it('resets cache and image', function () {
|
||||
openstreetcam.cache().foo = 'bar';
|
||||
openstreetcam.selectImage(context, {key: 'baz'});
|
||||
openstreetcam.selectImage(context, { key: 'baz' });
|
||||
|
||||
openstreetcam.reset();
|
||||
expect(openstreetcam.cache()).to.not.have.property('foo');
|
||||
@@ -50,18 +51,11 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#loadImages', function() {
|
||||
it('fires loadedImages when images are loaded', function(done) {
|
||||
openstreetcam.on('loadedImages', function() {
|
||||
expect(server.requests().length).to.eql(1); // 1 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
openstreetcam.loadImages(context.projection);
|
||||
|
||||
describe('#loadImages', function () {
|
||||
it('fires loadedImages when images are loaded', function (done) {
|
||||
var data = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems:[{
|
||||
currentPageItems: [{
|
||||
id: '1',
|
||||
sequence_id: '100',
|
||||
sequence_index: '1',
|
||||
@@ -101,21 +95,24 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
totalFilteredItems: ['3']
|
||||
};
|
||||
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(data) ]);
|
||||
server.respond();
|
||||
fetchMock.mock(new RegExp('/nearby-photos/'), {
|
||||
body: JSON.stringify(data),
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
openstreetcam.on('loadedImages', function () {
|
||||
expect(fetchMock.calls().length).to.eql(1); // 1 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
openstreetcam.loadImages(context.projection);
|
||||
});
|
||||
|
||||
it('does not load images around null island', function(done) {
|
||||
var spy = sinon.spy();
|
||||
context.projection.translate([0,0]);
|
||||
|
||||
openstreetcam.on('loadedImages', spy);
|
||||
openstreetcam.loadImages(context.projection);
|
||||
|
||||
it('does not load images around null island', function (done) {
|
||||
var data = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems:[{
|
||||
currentPageItems: [{
|
||||
id: '1',
|
||||
sequence_id: '100',
|
||||
sequence_index: '1',
|
||||
@@ -155,25 +152,26 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
totalFilteredItems: ['3']
|
||||
};
|
||||
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(data) ]);
|
||||
server.respond();
|
||||
var spy = sinon.spy();
|
||||
fetchMock.mock(new RegExp('/nearby-photos/'), {
|
||||
body: JSON.stringify(data),
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
window.setTimeout(function() {
|
||||
context.projection.translate([0, 0]);
|
||||
|
||||
openstreetcam.on('loadedImages', spy);
|
||||
openstreetcam.loadImages(context.projection);
|
||||
|
||||
window.setTimeout(function () {
|
||||
expect(spy).to.have.been.not.called;
|
||||
expect(server.requests().length).to.eql(0); // no tile requests of any kind
|
||||
expect(fetchMock.calls().length).to.eql(0); // no tile requests of any kind
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('loads multiple pages of image results', function(done) {
|
||||
openstreetcam.on('loadedImages', function() {
|
||||
expect(server.requests().length).to.eql(2); // 2 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
openstreetcam.loadImages(context.projection);
|
||||
|
||||
it('loads multiple pages of image results', function (done) {
|
||||
var features = [];
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var key = String(i);
|
||||
@@ -191,44 +189,54 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
username: 'test'
|
||||
});
|
||||
}
|
||||
|
||||
var response = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems: features,
|
||||
totalFilteredItems: ['1000']
|
||||
};
|
||||
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]);
|
||||
server.respond();
|
||||
fetchMock.mock(new RegExp('/nearby-photos/'), {
|
||||
body: JSON.stringify(response),
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
openstreetcam.on('loadedImages', function () {
|
||||
expect(fetchMock.calls().length).to.eql(2); // 2 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
openstreetcam.loadImages(context.projection);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#images', function() {
|
||||
it('returns images in the visible map area', function() {
|
||||
describe('#images', function () {
|
||||
it('returns images in the visible map area', function () {
|
||||
var features = [
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '0', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 0 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '1', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 1 } },
|
||||
{ minX: 10, minY: 1, maxX: 10, maxY: 1, data: { key: '2', loc: [10,1], ca: 90, sequence_id: '100', sequence_index: 2 } }
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '0', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 0 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '1', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 1 } },
|
||||
{ minX: 10, minY: 1, maxX: 10, maxY: 1, data: { key: '2', loc: [10, 1], ca: 90, sequence_id: '100', sequence_index: 2 } }
|
||||
];
|
||||
|
||||
openstreetcam.cache().images.rtree.load(features);
|
||||
var res = openstreetcam.images(context.projection);
|
||||
|
||||
expect(res).to.deep.eql([
|
||||
{ key: '0', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 0 },
|
||||
{ key: '1', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 1 }
|
||||
{ key: '0', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 0 },
|
||||
{ key: '1', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 1 }
|
||||
]);
|
||||
});
|
||||
|
||||
it('limits results no more than 5 stacked images in one spot', function() {
|
||||
it('limits results no more than 5 stacked images in one spot', function () {
|
||||
var features = [
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '0', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 0 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '1', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 1 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '2', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 2 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '3', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 3 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '4', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 4 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '5', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 5 } }
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '0', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 0 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '1', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 1 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '2', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 2 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '3', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 3 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '4', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 4 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '5', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 5 } }
|
||||
];
|
||||
|
||||
openstreetcam.cache().images.rtree.load(features);
|
||||
@@ -238,21 +246,21 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
});
|
||||
|
||||
|
||||
describe('#sequences', function() {
|
||||
it('returns sequence linestrings in the visible map area', function() {
|
||||
describe('#sequences', function () {
|
||||
it('returns sequence linestrings in the visible map area', function () {
|
||||
var features = [
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '0', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 0 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '1', loc: [10,0], ca: 90, sequence_id: '100', sequence_index: 1 } },
|
||||
{ minX: 10, minY: 1, maxX: 10, maxY: 1, data: { key: '2', loc: [10,1], ca: 90, sequence_id: '100', sequence_index: 2 } }
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '0', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 0 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: '1', loc: [10, 0], ca: 90, sequence_id: '100', sequence_index: 1 } },
|
||||
{ minX: 10, minY: 1, maxX: 10, maxY: 1, data: { key: '2', loc: [10, 1], ca: 90, sequence_id: '100', sequence_index: 2 } }
|
||||
];
|
||||
|
||||
openstreetcam.cache().images.rtree.load(features);
|
||||
openstreetcam.cache().sequences['100'] = { rotation: 0, images: [ features[0].data, features[1].data, features[2].data ] };
|
||||
openstreetcam.cache().sequences['100'] = { rotation: 0, images: [features[0].data, features[1].data, features[2].data] };
|
||||
|
||||
var res = openstreetcam.sequences(context.projection);
|
||||
expect(res).to.deep.eql([{
|
||||
type: 'LineString',
|
||||
coordinates: [[10,0], [10,0], [10,1]],
|
||||
coordinates: [[10, 0], [10, 0], [10, 1]],
|
||||
properties: {
|
||||
captured_at: undefined,
|
||||
captured_by: undefined,
|
||||
@@ -262,10 +270,10 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#selectedImage', function() {
|
||||
it('sets and gets selected image', function() {
|
||||
describe('#selectedImage', function () {
|
||||
it('sets and gets selected image', function () {
|
||||
var d = { key: 'foo' };
|
||||
openstreetcam.cache().images = { forImageKey: { foo: d }};
|
||||
openstreetcam.cache().images = { forImageKey: { foo: d } };
|
||||
openstreetcam.selectImage(context, 'foo');
|
||||
expect(openstreetcam.getSelectedImage()).to.eql(d);
|
||||
});
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
describe('iD.serviceStreetside', function() {
|
||||
describe('iD.serviceStreetside', function () {
|
||||
var dimensions = [64, 64];
|
||||
var context, streetside;
|
||||
|
||||
before(function() {
|
||||
before(function () {
|
||||
iD.services.streetside = iD.serviceStreetside;
|
||||
});
|
||||
|
||||
after(function() {
|
||||
after(function () {
|
||||
delete iD.services.streetside;
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
context = iD.coreContext().assetPath('../dist/').init();
|
||||
context.projection
|
||||
.scale(iD.geoZoomToScale(14))
|
||||
.translate([-116508, 0]) // 10,0
|
||||
.clipExtent([[0,0], dimensions]);
|
||||
.clipExtent([[0, 0], dimensions]);
|
||||
|
||||
streetside = iD.services.streetside;
|
||||
streetside.reset();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
window.JSONP_FIX = undefined;
|
||||
});
|
||||
|
||||
|
||||
describe('#init', function() {
|
||||
it('Initializes cache one time', function() {
|
||||
describe('#init', function () {
|
||||
it('Initializes cache one time', function () {
|
||||
var cache = streetside.cache();
|
||||
expect(cache).to.have.property('bubbles');
|
||||
expect(cache).to.have.property('sequences');
|
||||
@@ -38,82 +38,82 @@ describe('iD.serviceStreetside', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#reset', function() {
|
||||
it('resets cache', function() {
|
||||
describe('#reset', function () {
|
||||
it('resets cache', function () {
|
||||
streetside.cache().foo = 'bar';
|
||||
streetside.reset();
|
||||
expect(streetside.cache()).to.not.have.property('foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#loadBubbles', function() {
|
||||
it('fires loadedImages when bubbles are loaded', function(done) {
|
||||
describe('#loadBubbles', function () {
|
||||
it('fires loadedImages when bubbles are loaded', function (done) {
|
||||
// adjust projection so that only one tile is fetched
|
||||
// (JSONP hack will return the same data for every fetch)
|
||||
context.projection
|
||||
.scale(iD.geoZoomToScale(18))
|
||||
.translate([-1863988.9381333336, 762.8270222954452]) // 10.002,0.002
|
||||
.clipExtent([[0,0], dimensions]);
|
||||
.clipExtent([[0, 0], dimensions]);
|
||||
|
||||
var spy = sinon.spy();
|
||||
streetside.on('loadedImages', spy);
|
||||
|
||||
window.JSONP_DELAY = 0;
|
||||
window.JSONP_FIX = [{
|
||||
elapsed: 0.001
|
||||
}, {
|
||||
id: 1, la: 0, lo: 10.001, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:00 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: undefined, ne: 2
|
||||
}, {
|
||||
id: 2, la: 0, lo: 10.002, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:01 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 1, ne: 3
|
||||
}, {
|
||||
id: 3, la: 0, lo: 10.003, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:02 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 2, ne: undefined
|
||||
}
|
||||
elapsed: 0.001
|
||||
}, {
|
||||
id: 1, la: 0, lo: 10.001, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:00 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: undefined, ne: 2
|
||||
}, {
|
||||
id: 2, la: 0, lo: 10.002, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:01 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 1, ne: 3
|
||||
}, {
|
||||
id: 3, la: 0, lo: 10.003, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:02 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 2, ne: undefined
|
||||
}
|
||||
];
|
||||
|
||||
streetside.loadBubbles(context.projection, 0); // 0 = don't fetch margin tiles
|
||||
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('does not load bubbles around null island', function(done) {
|
||||
it('does not load bubbles around null island', function (done) {
|
||||
context.projection
|
||||
.scale(iD.geoZoomToScale(18))
|
||||
.translate([0, 0])
|
||||
.clipExtent([[0,0], dimensions]);
|
||||
.clipExtent([[0, 0], dimensions]);
|
||||
|
||||
var spy = sinon.spy();
|
||||
streetside.on('loadedImages', spy);
|
||||
|
||||
window.JSONP_DELAY = 0;
|
||||
window.JSONP_FIX = [{
|
||||
elapsed: 0.001
|
||||
}, {
|
||||
id: 1, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:00 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: undefined, ne: 2
|
||||
}, {
|
||||
id: 2, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:01 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 1, ne: 3
|
||||
}, {
|
||||
id: 3, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:02 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 2, ne: undefined
|
||||
}
|
||||
elapsed: 0.001
|
||||
}, {
|
||||
id: 1, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:00 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: undefined, ne: 2
|
||||
}, {
|
||||
id: 2, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:01 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 1, ne: 3
|
||||
}, {
|
||||
id: 3, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '',
|
||||
cd: '1/1/2018 12:00:02 PM', ml: 3, nbn: [], pbn: [], rn: [],
|
||||
pr: 2, ne: undefined
|
||||
}
|
||||
];
|
||||
|
||||
streetside.loadBubbles(context.projection, 0); // 0 = don't fetch margin tiles
|
||||
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(spy).to.have.been.not.called;
|
||||
done();
|
||||
}, 200);
|
||||
@@ -121,8 +121,8 @@ describe('iD.serviceStreetside', function() {
|
||||
});
|
||||
|
||||
|
||||
describe('#bubbles', function() {
|
||||
it('returns bubbles in the visible map area', function() {
|
||||
describe('#bubbles', function () {
|
||||
it('returns bubbles in the visible map area', function () {
|
||||
var features = [
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 1, loc: [10, 0], ca: 90, pr: undefined, ne: 2, pano: true, sequenceKey: 1 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 2, loc: [10, 0], ca: 90, pr: 1, ne: 3, pano: true, sequenceKey: 1 } },
|
||||
@@ -138,7 +138,7 @@ describe('iD.serviceStreetside', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('limits results no more than 5 stacked bubbles in one spot', function() {
|
||||
it('limits results no more than 5 stacked bubbles in one spot', function () {
|
||||
var features = [
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 1, loc: [10, 0], ca: 90, pr: undefined, ne: 2, pano: true, sequence_id: 1 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 2, loc: [10, 0], ca: 90, pr: 1, ne: 3, pano: true, sequence_id: 1 } },
|
||||
@@ -155,8 +155,8 @@ describe('iD.serviceStreetside', function() {
|
||||
});
|
||||
|
||||
|
||||
describe('#sequences', function() {
|
||||
it('returns sequence linestrings in the visible map area', function() {
|
||||
describe('#sequences', function () {
|
||||
it('returns sequence linestrings in the visible map area', function () {
|
||||
var features = [
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 1, loc: [10, 0], ca: 90, pr: undefined, ne: 2, pano: true, sequenceKey: 1 } },
|
||||
{ minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 2, loc: [10, 0], ca: 90, pr: 1, ne: 3, pano: true, sequenceKey: 1 } },
|
||||
@@ -167,11 +167,11 @@ describe('iD.serviceStreetside', function() {
|
||||
|
||||
var seq = {
|
||||
key: 1,
|
||||
bubbles: features.map(function(f) { return f.data; }),
|
||||
bubbles: features.map(function (f) { return f.data; }),
|
||||
geojson: {
|
||||
type: 'LineString',
|
||||
properties: { key: 1 },
|
||||
coordinates: features.map(function(f) { return f.data.loc; }),
|
||||
coordinates: features.map(function (f) { return f.data.loc; }),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
describe('iD.uiFieldWikipedia', function() {
|
||||
var entity, context, selection, field, server;
|
||||
describe('iD.uiFieldWikipedia', function () {
|
||||
var entity, context, selection, field;
|
||||
|
||||
before(function() {
|
||||
before(function () {
|
||||
iD.fileFetcher.cache().wmf_sitematrix = [
|
||||
['German','Deutsch','de'],
|
||||
['English','English','en']
|
||||
['German', 'Deutsch', 'de'],
|
||||
['English', 'English', 'en']
|
||||
];
|
||||
iD.services.wikipedia = iD.serviceWikipedia;
|
||||
iD.services.wikidata = iD.serviceWikidata;
|
||||
});
|
||||
|
||||
after(function() {
|
||||
after(function () {
|
||||
delete iD.fileFetcher.cache().wmf_sitematrix;
|
||||
delete iD.services.wikipedia;
|
||||
delete iD.services.wikidata;
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
entity = iD.osmNode({id: 'n12345'});
|
||||
beforeEach(function () {
|
||||
entity = iD.osmNode({ id: 'n12345' });
|
||||
context = iD.coreContext().assetPath('../dist/').init();
|
||||
context.history().merge([entity]);
|
||||
selection = d3.select(document.createElement('div'));
|
||||
@@ -26,11 +26,16 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
keys: ['wikipedia', 'wikidata'],
|
||||
type: 'wikipedia'
|
||||
});
|
||||
server = createServer({ respondImmediately: true });
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(new RegExp('\/w\/api\.php.*action=wbgetentities'), {
|
||||
body: '{"entities":{"Q216353":{"id":"Q216353"}}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
afterEach(function () {
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
|
||||
@@ -55,24 +60,11 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
}
|
||||
}
|
||||
|
||||
function createServer(options) { // eslint-disable-line no-unused-vars
|
||||
// note - currently skipping the tests that use `options` to delay responses
|
||||
// var server = sinon.fakeServer.create(options);
|
||||
var server = window.fakeFetch().create();
|
||||
server.respondWith('GET',
|
||||
new RegExp('\/w\/api\.php.*action=wbgetentities'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"entities":{"Q216353":{"id":"Q216353"}}}']
|
||||
);
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
it('recognizes lang:title format', function(done) {
|
||||
it('recognizes lang:title format', function (done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
window.setTimeout(function () { // async, so data will be available
|
||||
selection.call(wikipedia);
|
||||
wikipedia.tags({wikipedia: 'en:Title'});
|
||||
wikipedia.tags({ wikipedia: 'en:Title' });
|
||||
|
||||
expect(iD.utilGetSetValue(selection.selectAll('.wiki-lang'))).to.equal('English');
|
||||
expect(iD.utilGetSetValue(selection.selectAll('.wiki-title'))).to.equal('Title');
|
||||
@@ -80,9 +72,9 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it('sets language, value', function(done) {
|
||||
it('sets language, value', function (done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
window.setTimeout(function () { // async, so data will be available
|
||||
wikipedia.on('change', changeTags);
|
||||
selection.call(wikipedia);
|
||||
|
||||
@@ -98,17 +90,17 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
happen.once(selection.selectAll('.wiki-title').node(), { type: 'blur' });
|
||||
|
||||
expect(spy.callCount).to.equal(4);
|
||||
expect(spy.getCall(0)).to.have.been.calledWith({ wikipedia: undefined}); // lang on change
|
||||
expect(spy.getCall(1)).to.have.been.calledWith({ wikipedia: undefined}); // lang on blur
|
||||
expect(spy.getCall(0)).to.have.been.calledWith({ wikipedia: undefined }); // lang on change
|
||||
expect(spy.getCall(1)).to.have.been.calledWith({ wikipedia: undefined }); // lang on blur
|
||||
expect(spy.getCall(2)).to.have.been.calledWith({ wikipedia: 'de:Title' }); // title on change
|
||||
expect(spy.getCall(3)).to.have.been.calledWith({ wikipedia: 'de:Title' }); // title on blur
|
||||
done();
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it('recognizes pasted URLs', function(done) {
|
||||
it('recognizes pasted URLs', function (done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
window.setTimeout(function () { // async, so data will be available
|
||||
wikipedia.on('change', changeTags);
|
||||
selection.call(wikipedia);
|
||||
|
||||
@@ -121,14 +113,15 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it('preserves existing language', function(done) {
|
||||
// note - currently skipping the tests that use `options` to delay responses
|
||||
it('preserves existing language', function (done) {
|
||||
var wikipedia1 = iD.uiFieldWikipedia(field, context);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
window.setTimeout(function () { // async, so data will be available
|
||||
selection.call(wikipedia1);
|
||||
iD.utilGetSetValue(selection.selectAll('.wiki-lang'), 'Deutsch');
|
||||
|
||||
var wikipedia2 = iD.uiFieldWikipedia(field, context);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
window.setTimeout(function () { // async, so data will be available
|
||||
selection.call(wikipedia2);
|
||||
wikipedia2.tags({});
|
||||
expect(iD.utilGetSetValue(selection.selectAll('.wiki-lang'))).to.equal('Deutsch');
|
||||
@@ -137,7 +130,7 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it.skip('does not set delayed wikidata tag if graph has changed', function(done) {
|
||||
it.skip('does not set delayed wikidata tag if graph has changed', function (done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
wikipedia.on('change', changeTags);
|
||||
selection.call(wikipedia);
|
||||
@@ -146,7 +139,14 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
wikipedia.on('change.spy', spy);
|
||||
|
||||
// Create an XHR server that will respond after 60ms
|
||||
createServer({ autoRespond: true, autoRespondAfter: 60 });
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(new RegExp('\/w\/api\.php.*action=wbgetentities'), {
|
||||
body: '{"entities":{"Q216353":{"id":"Q216353"}}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}, {
|
||||
delay: 60
|
||||
});
|
||||
|
||||
// Set title to "Skip"
|
||||
iD.utilGetSetValue(selection.selectAll('.wiki-lang'), 'Deutsch');
|
||||
@@ -159,10 +159,17 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
|
||||
// Create a new XHR server that will respond after 60ms to
|
||||
// separate requests after this point from those before
|
||||
createServer({ autoRespond: true, autoRespondAfter: 60 });
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(new RegExp('\/w\/api\.php.*action=wbgetentities'), {
|
||||
body: '{"entities":{"Q216353":{"id":"Q216353"}}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}, {
|
||||
delay: 60
|
||||
});
|
||||
|
||||
// t30: graph change - Set title to "Title"
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
iD.utilGetSetValue(selection.selectAll('.wiki-title'), 'Title');
|
||||
happen.once(selection.selectAll('.wiki-title').node(), { type: 'change' });
|
||||
happen.once(selection.selectAll('.wiki-title').node(), { type: 'blur' });
|
||||
@@ -171,14 +178,14 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
// t60: at t0 + 60ms (delay), wikidata SHOULD NOT be set because graph has changed.
|
||||
|
||||
// t70: check that wikidata unchanged
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.entity(entity.id).tags.wikidata).to.be.undefined;
|
||||
}, 70);
|
||||
|
||||
// t90: at t30 + 60ms (delay), wikidata SHOULD be set because graph is unchanged.
|
||||
|
||||
// t100: check that wikidata has changed
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(function () {
|
||||
expect(context.entity(entity.id).tags.wikidata).to.equal('Q216353');
|
||||
|
||||
expect(spy.callCount).to.equal(4);
|
||||
|
||||
Reference in New Issue
Block a user