osrm-backend/features/support/shared_steps.js

283 lines
13 KiB
JavaScript
Raw Normal View History

'use strict';
2016-03-04 15:11:05 -05:00
var util = require('util');
var assert = require('assert');
module.exports = function () {
this.ShouldGetAResponse = () => {
assert.equal(this.response.statusCode, 200);
assert.ok(this.response.body);
assert.ok(this.response.body.length);
};
this.ShouldBeValidJSON = (callback) => {
try {
this.json = JSON.parse(this.response.body);
callback();
} catch (e) {
callback(e);
}
};
this.ShouldBeWellFormed = () => {
assert.equal(typeof this.json.status, 'number');
};
this.WhenIRouteIShouldGet = (table, callback) => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
2016-03-04 15:11:05 -05:00
var headers = new Set(table.raw()[0]);
var requestRow = (row, ri, cb) => {
var got;
2016-03-04 15:11:05 -05:00
var afterRequest = (err, res, body) => {
if (err) return cb(err);
if (body && body.length) {
let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, classes,
distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches,
driving_sides;
2016-03-04 15:11:05 -05:00
let json = JSON.parse(body);
2016-03-04 15:11:05 -05:00
got.code = json.code;
let hasRoute = json.code === 'Ok';
2016-03-04 15:11:05 -05:00
if (hasRoute) {
instructions = this.wayList(json.routes[0]);
pronunciations = this.pronunciationList(json.routes[0]);
2016-09-05 09:01:51 -04:00
refs = this.refList(json.routes[0]);
2016-05-26 18:47:46 -04:00
destinations = this.destinationsList(json.routes[0]);
exits = this.exitsList(json.routes[0]);
bearings = this.bearingList(json.routes[0]);
turns = this.turnList(json.routes[0]);
intersections = this.intersectionList(json.routes[0]);
modes = this.modeList(json.routes[0]);
driving_sides = this.drivingSideList(json.routes[0]);
classes = this.classesList(json.routes[0]);
times = this.timeList(json.routes[0]);
distances = this.distanceList(json.routes[0]);
2016-05-13 13:18:00 -04:00
lanes = this.lanesList(json.routes[0]);
summary = this.summary(json.routes[0]);
locations = this.locations(json.routes[0]);
annotation = this.annotationList(json.routes[0]);
weight_name = this.weightName(json.routes[0]);
weights = this.weightList(json.routes[0]);
approaches = this.approachList(json.routes[0]);
2016-03-04 15:11:05 -05:00
}
if (headers.has('status')) {
2016-03-29 21:30:37 -04:00
got.status = res.statusCode.toString();
2016-03-04 15:11:05 -05:00
}
if (headers.has('message')) {
2016-03-29 21:30:37 -04:00
got.message = json.message || '';
2016-03-04 15:11:05 -05:00
}
if (headers.has('data_version')) {
got.data_version = json.data_version || '';
}
2016-03-04 15:11:05 -05:00
if (headers.has('#')) {
// comment column
got['#'] = row['#'];
}
if (headers.has('geometry')) {
2016-03-30 21:47:11 -04:00
got.geometry = json.routes[0].geometry;
2016-03-04 15:11:05 -05:00
}
if (headers.has('route')) {
got.route = (instructions || '').trim();
}
2016-03-04 15:11:05 -05:00
if (headers.has('summary')) {
got.summary = (summary || '').trim();
}
2016-03-04 15:11:05 -05:00
if (headers.has('alternative')) {
// TODO examine more than first alternative?
got.alternative ='';
if (json.routes && json.routes.length > 1)
got.alternative = this.wayList(json.routes[1]);
}
2016-03-04 15:11:05 -05:00
var distance = hasRoute && json.routes[0].distance,
time = hasRoute && json.routes[0].duration,
weight = hasRoute && json.routes[0].weight;
if (headers.has('distance')) {
if (row.distance.length) {
if (!row.distance.match(/\d+m/))
return cb(new Error('*** Distance must be specified in meters. (ex: 250m)'));
got.distance = instructions ? util.format('%dm', distance) : '';
} else {
got.distance = '';
}
}
if (headers.has('weight')) {
if (row.weight.length) {
if (!row.weight.match(/[\d.]+/))
return cb(new Error('*** Weight must be specified as a numeric value. (ex: 8)'));
got.weight = instructions ? util.format('%d', weight) : '';
} else {
got.weight = '';
2016-03-04 15:11:05 -05:00
}
}
2016-03-04 15:11:05 -05:00
if (headers.has('time')) {
if (!row.time.match(/\d+s/))
return cb(new Error('*** Time must be specied in seconds. (ex: 60s)'));
got.time = instructions ? util.format('%ds', time) : '';
}
2016-05-13 13:18:00 -04:00
if (headers.has('lanes')) {
got.lanes = (lanes || '').trim();
}
2016-03-04 15:11:05 -05:00
if (headers.has('speed')) {
if (row.speed !== '' && instructions) {
if (!row.speed.match(/\d+ km\/h/))
cb(new Error('*** Speed must be specied in km/h. (ex: 50 km/h)'));
var speed = time > 0 ? Math.round(3.6*distance/time) : null;
got.speed = util.format('%d km/h', speed);
} else {
got.speed = '';
}
}
if (headers.has('intersections')) {
got.intersections = (intersections || '').trim();
}
if (headers.has('locations')){
got.locations = (locations || '').trim();
2016-03-04 15:11:05 -05:00
}
/*
if (headers.has('approaches')){
got.approaches = (approaches || '').trim();
}*/
// if header matches 'a:*', parse out the values for *
// and return in that header
headers.forEach((k) => {
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed' ];
let metadata_whitelist = [ 'datasource_names' ];
if (k.match(/^a:/)) {
let a_type = k.slice(2);
if (whitelist.indexOf(a_type) == -1)
return cb(new Error('Unrecognized annotation field', a_type));
if (annotation && !annotation[a_type])
return cb(new Error('Annotation not found in response', a_type));
got[k] = annotation && annotation[a_type] || '';
} else if (k.match(/^am:/)) {
let a_type = k.slice(3);
if (metadata_whitelist.indexOf(a_type) == -1)
return cb(new Error('Unrecognized annotation field', a_type));
if (annotation && (!annotation.metadata || !annotation.metadata[a_type]))
return cb(new Error('Annotation not found in response', a_type));
got[k] = (annotation && annotation.metadata && annotation.metadata[a_type]) || '';
}
});
var putValue = (key, value) => {
if (headers.has(key)) got[key] = instructions ? value : '';
};
putValue('ref', refs);
putValue('bearing', bearings);
putValue('turns', turns);
putValue('modes', modes);
putValue('classes', classes);
putValue('times', times);
putValue('distances', distances);
putValue('pronunciations', pronunciations);
putValue('destinations', destinations);
putValue('exits', exits);
putValue('weight_name', weight_name);
putValue('weights', weights);
putValue('weight', weight);
putValue('approach', approaches);
if (driving_sides) {
putValue('driving_side', driving_sides);
}
2016-03-04 15:11:05 -05:00
for (var key in row) {
if (this.FuzzyMatch.match(got[key], row[key])) {
got[key] = row[key];
}
}
cb(null, got);
} else {
cb(new Error('request failed to return valid body'));
}
};
if (headers.has('request')) {
got = { request: row.request };
this.requestUrl(row.request, afterRequest);
} else {
var defaultParams = this.queryParams;
var userParams = [];
got = {};
for (var k in row) {
var match = k.match(/param:(.*)/);
if (match) {
if (row[k] === '(nil)') {
userParams.push([match[1], null]);
} else if (row[k]) {
userParams.push([match[1], row[k]]);
}
got[k] = row[k];
}
}
var params = this.overwriteParams(defaultParams, userParams),
waypoints = [],
bearings = [],
approaches = [];
2016-03-04 15:11:05 -05:00
if (row.bearings) {
got.bearings = row.bearings;
bearings = row.bearings.split(' ').filter(b => !!b);
}
if (row.approaches) {
got.approaches = row.approaches;
approaches = row.approaches.split(' ').filter(b => !!b);
}
2016-03-04 15:11:05 -05:00
if (row.from && row.to) {
var fromNode = this.findNodeByName(row.from);
if (!fromNode) return cb(new Error(util.format('*** unknown from-node "%s"', row.from)));
2016-03-04 15:11:05 -05:00
waypoints.push(fromNode);
var toNode = this.findNodeByName(row.to);
if (!toNode) return cb(new Error(util.format('*** unknown to-node "%s"', row.to)));
2016-03-04 15:11:05 -05:00
waypoints.push(toNode);
got.from = row.from;
got.to = row.to;
this.requestRoute(waypoints, bearings, approaches, params, afterRequest);
2016-03-04 15:11:05 -05:00
} else if (row.waypoints) {
row.waypoints.split(',').forEach((n) => {
var node = this.findNodeByName(n.trim());
2017-06-30 07:10:17 -04:00
if (!node) return cb(new Error(util.format('*** unknown waypoint node "%s"', n.trim())));
2016-03-04 15:11:05 -05:00
waypoints.push(node);
});
got.waypoints = row.waypoints;
this.requestRoute(waypoints, bearings, approaches, params, afterRequest);
2016-03-04 15:11:05 -05:00
} else {
return cb(new Error('*** no waypoints'));
2016-03-04 15:11:05 -05:00
}
}
};
this.processRowsAndDiff(table, requestRow, callback);
});
};
};