mirror of https://github.com/pelias/api.git
Julian Simioni
9 years ago
116 changed files with 2969 additions and 1821 deletions
@ -1,6 +1,23 @@ |
|||||||
|
sudo: false |
||||||
language: node_js |
language: node_js |
||||||
script: "npm run unit" |
|
||||||
node_js: |
node_js: |
||||||
- "0.10" |
- 0.10 |
||||||
- "0.12" |
- 0.12 |
||||||
sudo: false |
- 4.4 |
||||||
|
- 5.8 |
||||||
|
matrix: |
||||||
|
allow_failures: |
||||||
|
- node_js: 4.4 |
||||||
|
- node_js: 5.8 |
||||||
|
env: |
||||||
|
global: |
||||||
|
- CXX=g++-4.8 |
||||||
|
matrix: |
||||||
|
- TEST_SUITE=unit |
||||||
|
script: "npm run $TEST_SUITE" |
||||||
|
addons: |
||||||
|
apt: |
||||||
|
sources: |
||||||
|
- ubuntu-toolchain-r-test |
||||||
|
packages: |
||||||
|
- g++-4.8 |
||||||
|
@ -1,9 +0,0 @@ |
|||||||
|
|
||||||
#### Search: |
|
||||||
|
|
||||||
- Nearest Museums: http://pelias.mapzen.com/search?lat=51.533&lon=-0.0652&input=museum&size=40 |
|
||||||
- Nearest Hotels: http://pelias.mapzen.com/search?lat=51.533&lon=-0.0652&input=hotel&size=40 |
|
||||||
|
|
||||||
#### Autocomplete: |
|
||||||
|
|
||||||
- Local Neighborhoods: http://pelias.mapzen.com/suggest/nearby?lat=40.7259&lon=-73.9806&input=e&layers=neighborhood&size=40 |
|
@ -0,0 +1,9 @@ |
|||||||
|
#!/bin/bash -ex |
||||||
|
|
||||||
|
rm -r docs || true |
||||||
|
|
||||||
|
curl -s http://localhost:3100/v1 > /dev/null || die "Pelias server does not appear to be running \ |
||||||
|
on http://localhost:3100, run npm start in another window before generating docs." |
||||||
|
|
||||||
|
cd test/ciao |
||||||
|
node ../../node_modules/ciao/bin/ciao -c ../ciao.json . -d ../../docs |
@ -1,45 +0,0 @@ |
|||||||
|
|
||||||
var _ = require('lodash'), |
|
||||||
peliasSchema = require('pelias-schema'), |
|
||||||
peliasLogger = require( 'pelias-logger' ).get( 'api' ); |
|
||||||
|
|
||||||
var ADMIN_FIELDS = [ |
|
||||||
'admin0', |
|
||||||
'admin1', |
|
||||||
'admin1_abbr', |
|
||||||
'admin2', |
|
||||||
'local_admin', |
|
||||||
'locality', |
|
||||||
'neighborhood', |
|
||||||
'address.zip' |
|
||||||
]; |
|
||||||
|
|
||||||
/** |
|
||||||
* Get all admin fields that were expected and also found in schema |
|
||||||
* |
|
||||||
* @param {Object} [schema] optional: for testing only |
|
||||||
* @param {Array} [expectedFields] optional: for testing only |
|
||||||
* @param {Object} [logger] optional: for testing only |
|
||||||
* @returns {Array.<string>} |
|
||||||
*/ |
|
||||||
function getAvailableAdminFields(schema, expectedFields, logger) { |
|
||||||
|
|
||||||
schema = schema || peliasSchema; |
|
||||||
expectedFields = expectedFields || ADMIN_FIELDS; |
|
||||||
logger = logger || peliasLogger; |
|
||||||
|
|
||||||
var actualFields = Object.keys(schema.mappings._default_.properties); |
|
||||||
|
|
||||||
// check if expected fields are actually in current schema
|
|
||||||
var available = expectedFields.filter(function (field) { |
|
||||||
return _.contains( actualFields, field ); |
|
||||||
}); |
|
||||||
|
|
||||||
if (available.length === 0) { |
|
||||||
logger.error('helper/adminFields: no expected admin fields found in schema'); |
|
||||||
} |
|
||||||
|
|
||||||
return available; |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = getAvailableAdminFields; |
|
@ -1,35 +1,74 @@ |
|||||||
|
|
||||||
var _ = require('lodash'), |
var _ = require('lodash'), |
||||||
check = require('check-types'), |
schemas = require('./labelSchema'); |
||||||
schemas = require('./labelSchema.json'); |
|
||||||
|
|
||||||
module.exports = function( record ){ |
module.exports = function( record ){ |
||||||
|
var schema = getSchema(record.country_a); |
||||||
|
|
||||||
|
var labelParts = getInitialLabel(record); |
||||||
|
|
||||||
var labelParts = [ record.name.default ]; |
for (var key in schema) { |
||||||
|
var valueFunction = schema[key]; |
||||||
|
|
||||||
var schema = schemas.default; |
labelParts = valueFunction(record, labelParts); |
||||||
|
|
||||||
if (record.country_a && record.country_a.length && schemas[record.country_a]) { |
|
||||||
schema = schemas[record.country_a]; |
|
||||||
} |
} |
||||||
|
|
||||||
var buildOutput = function(parts, schemaArr, record) { |
|
||||||
for (var i=0; i<schemaArr.length; i++) { |
|
||||||
var fieldValue = record[schemaArr[i]]; |
|
||||||
if (check.unemptyString(fieldValue) && !_.contains(parts, fieldValue)) { |
|
||||||
parts.push( fieldValue ); |
|
||||||
return parts; |
|
||||||
} |
|
||||||
} |
|
||||||
return parts; |
|
||||||
}; |
|
||||||
|
|
||||||
for (var key in schema) { |
// NOTE: while it may seem odd to call `uniq` on the list of label parts,
|
||||||
labelParts = buildOutput(labelParts, schema[key], record); |
// the effect is quite subtle. Take, for instance, a result for "Lancaster, PA"
|
||||||
|
// the pseudo-object is:
|
||||||
|
// {
|
||||||
|
// 'name': 'Lancaster',
|
||||||
|
// 'locality': 'Lancaster',
|
||||||
|
// 'region_a': 'PA',
|
||||||
|
// 'country_a': 'USA'
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// the code up to this point generates the label:
|
||||||
|
// `Lancaster, Lancaster, PA, USA`
|
||||||
|
//
|
||||||
|
// then the `unique` call reduces this to:
|
||||||
|
// `Lancaster, PA, USA`
|
||||||
|
//
|
||||||
|
// this code doesn't have the same effect in the case of a venue or address
|
||||||
|
// where the `name` field would contain the address or name of a point-of-interest
|
||||||
|
//
|
||||||
|
// Also see https://github.com/pelias/api/issues/429 for other ways that this is bad
|
||||||
|
//
|
||||||
|
// de-dupe, join, trim
|
||||||
|
return _.uniq( labelParts ).join(', ').trim(); |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
function getSchema(country_a) { |
||||||
|
if (country_a && country_a.length && schemas[country_a]) { |
||||||
|
return schemas[country_a]; |
||||||
|
} |
||||||
|
|
||||||
|
return schemas.default; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// helper function that sets a default label for non-US/CA regions
|
||||||
|
// this is a very special case
|
||||||
|
function getInitialLabel(record) { |
||||||
|
if (isRegion(record.layer) && |
||||||
|
isGeonamesOrWhosOnFirst(record.source) && |
||||||
|
isUSAOrCAN(record.country_a)) { |
||||||
|
return []; |
||||||
} |
} |
||||||
|
|
||||||
// de-dupe outputs
|
return [record.name]; |
||||||
labelParts = _.unique( labelParts ); |
|
||||||
|
} |
||||||
|
|
||||||
|
function isRegion(layer) { |
||||||
|
return 'region' === layer; |
||||||
|
} |
||||||
|
|
||||||
|
function isUSAOrCAN(country_a) { |
||||||
|
return 'USA' === country_a || 'CAN' === country_a; |
||||||
|
} |
||||||
|
|
||||||
|
function isGeonamesOrWhosOnFirst(source) { |
||||||
|
return 'geonames' === source || 'whosonfirst' === source; |
||||||
|
|
||||||
return labelParts.join(', ').trim(); |
} |
||||||
}; |
|
||||||
|
@ -0,0 +1,66 @@ |
|||||||
|
var _ = require('lodash'), |
||||||
|
check = require('check-types'); |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
'USA': { |
||||||
|
'local': getFirstProperty(['localadmin', 'locality', 'neighbourhood', 'county']), |
||||||
|
'regional': getUsState, |
||||||
|
'country': getFirstProperty(['country_a']) |
||||||
|
}, |
||||||
|
'GBR': { |
||||||
|
'local': getFirstProperty(['neighbourhood', 'county', 'localadmin', 'locality', 'macroregion', 'region']), |
||||||
|
'regional': getFirstProperty(['county','country','region']) |
||||||
|
}, |
||||||
|
'SGP': { |
||||||
|
'local': getFirstProperty(['neighbourhood', 'region', 'county', 'localadmin', 'locality']), |
||||||
|
'regional': getFirstProperty(['county','country','region']) |
||||||
|
}, |
||||||
|
'SWE': { |
||||||
|
'local': getFirstProperty(['neighbourhood', 'region', 'county', 'localadmin', 'locality']), |
||||||
|
'regional': getFirstProperty(['country']) |
||||||
|
}, |
||||||
|
'default': { |
||||||
|
'local': getFirstProperty(['localadmin', 'locality', 'neighbourhood', 'county', 'macroregion', 'region']), |
||||||
|
'regional': getFirstProperty(['country']) |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// find the first field of record that has a non-empty value that's not already in labelParts
|
||||||
|
function getFirstProperty(fields) { |
||||||
|
return function(record, labelParts) { |
||||||
|
for (var i = 0; i < fields.length; i++) { |
||||||
|
var fieldValue = record[fields[i]]; |
||||||
|
|
||||||
|
if (check.nonEmptyString(fieldValue) && !_.includes(labelParts, fieldValue)) { |
||||||
|
labelParts.push( fieldValue ); |
||||||
|
return labelParts; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return labelParts; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// this function is exclusively used for figuring out which field to use for US States
|
||||||
|
// 1. if a US state is the most granular bit of info entered, the label should contain
|
||||||
|
// the full state name, eg: Pennsylvania, USA
|
||||||
|
// 2. otherwise, the state abbreviation should be used, eg: Lancaster, PA, USA
|
||||||
|
// 3. if for some reason the abbreviation isn't available, use the full state name
|
||||||
|
function getUsState(record, labelParts) { |
||||||
|
if ('region' === record.layer && record.region) { |
||||||
|
// add full state name when state is the most granular piece of info
|
||||||
|
labelParts.push(record.region); |
||||||
|
} else if (record.region_a) { |
||||||
|
// otherwise just add the region code when available
|
||||||
|
labelParts.push(record.region_a); |
||||||
|
} else if (record.region) { |
||||||
|
// add the full name when there's no region code available ()
|
||||||
|
labelParts.push(record.region); |
||||||
|
} |
||||||
|
|
||||||
|
return labelParts; |
||||||
|
|
||||||
|
} |
@ -1,22 +0,0 @@ |
|||||||
{ |
|
||||||
"USA": { |
|
||||||
"local": ["localadmin", "locality", "neighbourhood", "county"], |
|
||||||
"regional": ["region_a", "region", "country"] |
|
||||||
}, |
|
||||||
"GBR": { |
|
||||||
"local": ["neighbourhood", "county", "localadmin", "locality", "region"], |
|
||||||
"regional": ["county","country","region"] |
|
||||||
}, |
|
||||||
"SGP": { |
|
||||||
"local": ["neighbourhood", "region", "county", "localadmin", "locality"], |
|
||||||
"regional": ["county","country","region"] |
|
||||||
}, |
|
||||||
"SWE": { |
|
||||||
"local": ["neighbourhood", "region", "county", "localadmin", "locality"], |
|
||||||
"regional": ["country"] |
|
||||||
}, |
|
||||||
"default": { |
|
||||||
"local": ["localadmin", "locality", "neighbourhood", "county", "region"], |
|
||||||
"regional": ["country"] |
|
||||||
} |
|
||||||
} |
|
@ -1,87 +1,81 @@ |
|||||||
var extend = require('extend'), |
var extend = require('extend'), |
||||||
_ = require('lodash'); |
_ = require('lodash'); |
||||||
|
|
||||||
var TYPE_TO_SOURCE = { |
function addStandardTargetsToAliases(standard, aliases) { |
||||||
'geoname': 'gn', |
var combined = _.extend({}, aliases); |
||||||
'osmnode': 'osm', |
standard.forEach(function(target) { |
||||||
'osmway': 'osm', |
if (combined[target] === undefined) { |
||||||
'admin0': 'qs', |
combined[target] = [target]; |
||||||
'admin1': 'qs', |
} |
||||||
'admin2': 'qs', |
}); |
||||||
'neighborhood': 'qs', |
|
||||||
'locality': 'qs', |
return combined; |
||||||
'local_admin': 'qs', |
} |
||||||
'osmaddress': 'osm', |
|
||||||
'openaddresses': 'oa' |
|
||||||
}; |
|
||||||
|
|
||||||
/* |
/* |
||||||
* This doesn't include alias layers such as coarse |
* Sources |
||||||
*/ |
*/ |
||||||
var TYPE_TO_LAYER = { |
|
||||||
'geoname': 'venue', |
|
||||||
'osmnode': 'venue', |
|
||||||
'osmway': 'venue', |
|
||||||
'admin0': 'country', |
|
||||||
'admin1': 'region', |
|
||||||
'admin2': 'county', |
|
||||||
'neighborhood': 'neighbourhood', |
|
||||||
'locality': 'locality', |
|
||||||
'local_admin': 'localadmin', |
|
||||||
'osmaddress': 'address', |
|
||||||
'openaddresses': 'address' |
|
||||||
}; |
|
||||||
|
|
||||||
var SOURCE_TO_TYPE = { |
// a list of all sources
|
||||||
'gn' : ['geoname'], |
var SOURCES = ['openstreetmap', 'openaddresses', 'geonames', 'whosonfirst']; |
||||||
'geonames' : ['geoname'], |
|
||||||
'oa' : ['openaddresses'], |
/* |
||||||
'openaddresses' : ['openaddresses'], |
* A list of alternate names for sources, mostly used to save typing |
||||||
'qs' : ['admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin'], |
*/ |
||||||
'quattroshapes' : ['admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin'], |
var SOURCE_ALIASES = { |
||||||
'osm' : ['osmaddress', 'osmnode', 'osmway'], |
'osm': ['openstreetmap'], |
||||||
'openstreetmap' : ['osmaddress', 'osmnode', 'osmway'] |
'oa': ['openaddresses'], |
||||||
|
'gn': ['geonames'], |
||||||
|
'wof': ['whosonfirst'] |
||||||
}; |
}; |
||||||
|
|
||||||
/** |
/* |
||||||
* This does not included alias layers, those are built separately |
* Create an object that contains all sources or aliases. The key is the source or alias, |
||||||
|
* the value is either that source, or the canonical name for that alias if it's an alias. |
||||||
*/ |
*/ |
||||||
var LAYER_TO_TYPE = { |
var SOURCE_MAPPING = addStandardTargetsToAliases(SOURCES, SOURCE_ALIASES); |
||||||
'venue': ['geoname','osmnode','osmway'], |
|
||||||
'address': ['osmaddress','openaddresses'], |
/* |
||||||
'country': ['admin0'], |
* Layers |
||||||
'region': ['admin1'], |
*/ |
||||||
'county': ['admin2'], |
|
||||||
'locality': ['locality'], |
/* |
||||||
'localadmin': ['local_admin'], |
* A list of all layers in each source. This is used for convenience elswhere |
||||||
'neighbourhood': ['neighborhood'] |
* and to determine when a combination of source and layer parameters is |
||||||
|
* not going to match any records and will return no results. |
||||||
|
*/ |
||||||
|
var LAYERS_BY_SOURCE = { |
||||||
|
openstreetmap: [ 'address', 'venue' ], |
||||||
|
openaddresses: [ 'address' ], |
||||||
|
geonames: [ 'country', 'region', 'county', 'locality', 'venue' ], |
||||||
|
whosonfirst: [ 'continent', 'macrocountry', 'country', 'dependency', 'region', |
||||||
|
'locality', 'localadmin', 'county', 'macrohood', 'neighbourhood', 'microhood', 'disputed'] |
||||||
}; |
}; |
||||||
|
|
||||||
|
/* |
||||||
|
* A list of layer aliases that can be used to support specific use cases |
||||||
|
* (like coarse geocoding) * or work around the fact that different sources |
||||||
|
* may have layers that mean the same thing but have a different name |
||||||
|
*/ |
||||||
var LAYER_ALIASES = { |
var LAYER_ALIASES = { |
||||||
'coarse': ['admin0','admin1','admin2','neighborhood','locality','local_admin'] |
'coarse': LAYERS_BY_SOURCE.whosonfirst |
||||||
}; |
}; |
||||||
|
|
||||||
var LAYER_WITH_ALIASES_TO_TYPE = extend({}, LAYER_ALIASES, LAYER_TO_TYPE); |
// create a list of all layers by combining each entry from LAYERS_BY_SOURCE
|
||||||
|
var LAYERS = _.uniq(Object.keys(LAYERS_BY_SOURCE).reduce(function(acc, key) { |
||||||
|
return acc.concat(LAYERS_BY_SOURCE[key]); |
||||||
|
}, [])); |
||||||
|
|
||||||
/* |
/* |
||||||
* derive the list of types, sources, and layers from above mappings |
* Create the an object that has a key for each possible layer or alias, |
||||||
|
* and returns either that layer, or all the layers in the alias |
||||||
*/ |
*/ |
||||||
var TYPES = Object.keys(TYPE_TO_SOURCE); |
var LAYER_MAPPING = addStandardTargetsToAliases(LAYERS, LAYER_ALIASES); |
||||||
var SOURCES = Object.keys(SOURCE_TO_TYPE); |
|
||||||
var LAYERS = Object.keys(LAYER_TO_TYPE); |
|
||||||
|
|
||||||
var sourceAndLayerToType = function sourceAndLayerToType(source, layer) { |
|
||||||
return _.intersection(SOURCE_TO_TYPE[source], LAYER_WITH_ALIASES_TO_TYPE[layer]); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
types: TYPES, |
|
||||||
sources: SOURCES, |
sources: SOURCES, |
||||||
layers: LAYERS, |
layers: LAYERS, |
||||||
type_to_source: TYPE_TO_SOURCE, |
source_mapping: SOURCE_MAPPING, |
||||||
type_to_layer: TYPE_TO_LAYER, |
layer_mapping: LAYER_MAPPING, |
||||||
source_to_type: SOURCE_TO_TYPE, |
layers_by_source: LAYERS_BY_SOURCE |
||||||
layer_to_type: LAYER_TO_TYPE, |
|
||||||
layer_with_aliases_to_type: LAYER_WITH_ALIASES_TO_TYPE, |
|
||||||
source_and_layer_to_type: sourceAndLayerToType |
|
||||||
}; |
}; |
||||||
|
@ -1,43 +0,0 @@ |
|||||||
var type_mapping = require( '../helper/type_mapping' ); |
|
||||||
var _ = require('lodash'); |
|
||||||
|
|
||||||
/** |
|
||||||
* Different parts of the code express "preferences" for which Elasticsearch types are going to be searched |
|
||||||
* This method decides how to combine all the preferences. |
|
||||||
* |
|
||||||
* @param {Array} clean_types |
|
||||||
* @returns {Array} |
|
||||||
*/ |
|
||||||
module.exports = function calculate_types(clean_types) { |
|
||||||
//Check that at least one preference of types is defined
|
|
||||||
if (!clean_types || !(clean_types.from_layers || clean_types.from_sources || clean_types.from_text_parser)) { |
|
||||||
throw new Error('clean_types should not be null or undefined'); |
|
||||||
} |
|
||||||
|
|
||||||
/* the layers and source parameters are cumulative: |
|
||||||
* perform a set intersection of their specified types |
|
||||||
*/ |
|
||||||
if (clean_types.from_layers || clean_types.from_sources) { |
|
||||||
var types = type_mapping.types; |
|
||||||
|
|
||||||
if (clean_types.from_layers) { |
|
||||||
types = _.intersection(types, clean_types.from_layers); |
|
||||||
} |
|
||||||
|
|
||||||
if (clean_types.from_sources) { |
|
||||||
types = _.intersection(types, clean_types.from_sources); |
|
||||||
} |
|
||||||
|
|
||||||
return types; |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* Type restrictions requested by the address parser should only be used |
|
||||||
* if both the source and layers parameters are empty, so do this last |
|
||||||
*/ |
|
||||||
if (clean_types.from_text_parser) { |
|
||||||
return clean_types.from_text_parser; |
|
||||||
} |
|
||||||
|
|
||||||
throw new Error('no types specified'); |
|
||||||
}; |
|
@ -1,46 +0,0 @@ |
|||||||
var types_helper = require( '../helper/types' ); |
|
||||||
|
|
||||||
/** |
|
||||||
* Validate the types specified to be searched. |
|
||||||
* |
|
||||||
* Elasticsearch interprets an empty array of types as "search anything" rather |
|
||||||
* than "search nothing", so in the case of an empty array, return an error |
|
||||||
* message instead of searching at all. |
|
||||||
*/ |
|
||||||
function middleware(req, res, next) { |
|
||||||
req.clean = req.clean || {}; |
|
||||||
|
|
||||||
if (req.clean.hasOwnProperty('types')) { |
|
||||||
|
|
||||||
try { |
|
||||||
var types = types_helper(req.clean.types); |
|
||||||
|
|
||||||
if ((types instanceof Array) && types.length === 0) { |
|
||||||
var err = 'You have specified both the `sources` and `layers` ' + |
|
||||||
'parameters in a combination that will return no results.'; |
|
||||||
req.errors.push( err ); |
|
||||||
} |
|
||||||
|
|
||||||
else { |
|
||||||
req.clean.type = types; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
// @todo: refactor this flow, it is confusing as `types_helper()` can throw
|
|
||||||
// with an error "clean_types should not be null or undefined" which is
|
|
||||||
// not returned to the user yet the return value CAN trigger a user error.
|
|
||||||
// I would have liked to throw for BOTH cases and then handle the users errors
|
|
||||||
// inside the 'catch' but this is not possible.
|
|
||||||
// also: why are we deleting things from $clean?
|
|
||||||
catch (err) { |
|
||||||
// this means there were no types specified
|
|
||||||
delete req.clean.types; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
next(); |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = middleware; |
|
@ -0,0 +1,38 @@ |
|||||||
|
var logger = require('pelias-logger').get('api'); |
||||||
|
|
||||||
|
/** |
||||||
|
* Parses the bounding box property in docs, if one is found |
||||||
|
*/ |
||||||
|
|
||||||
|
function setup() { |
||||||
|
return function (req, res, next) { |
||||||
|
// do nothing if no result data set
|
||||||
|
if (!res || !res.data) { |
||||||
|
return next(); |
||||||
|
} |
||||||
|
|
||||||
|
res.data = res.data.map(parseBBox); |
||||||
|
|
||||||
|
next(); |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* Parse the bbox property and form an object |
||||||
|
*/ |
||||||
|
function parseBBox(place) { |
||||||
|
|
||||||
|
if (place && place.bounding_box) { |
||||||
|
try { |
||||||
|
place.bounding_box = JSON.parse(place.bounding_box); |
||||||
|
} |
||||||
|
catch (err) { |
||||||
|
logger.error('Invalid bounding_box json string:', place); |
||||||
|
delete place.bounding_box; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return place; |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = setup; |
@ -1,46 +0,0 @@ |
|||||||
|
|
||||||
var _ = require('lodash'), |
|
||||||
check = require('check-types'), |
|
||||||
sources_map = require( '../query/sources' ); |
|
||||||
|
|
||||||
var ALL_SOURCES = Object.keys(sources_map), |
|
||||||
ALL_SOURCES_JOINED = ALL_SOURCES.join(','); |
|
||||||
|
|
||||||
function sanitize( raw, clean ) { |
|
||||||
|
|
||||||
// error & warning messages
|
|
||||||
var messages = { errors: [], warnings: [] }; |
|
||||||
|
|
||||||
// init clean.types (if not already init)
|
|
||||||
clean.types = clean.types || {}; |
|
||||||
|
|
||||||
// default case (no layers specified in GET params)
|
|
||||||
// don't even set the from_layers key in this case
|
|
||||||
if( check.unemptyString( raw.source ) ){ |
|
||||||
|
|
||||||
var sources = raw.source.split(','); |
|
||||||
|
|
||||||
var invalid_sources = sources.filter(function(source) { |
|
||||||
return !_.contains( ALL_SOURCES, source ); |
|
||||||
}); |
|
||||||
|
|
||||||
if( invalid_sources.length > 0 ){ |
|
||||||
invalid_sources.forEach( function( invalid ){ |
|
||||||
messages.errors.push('\'' + invalid + '\' is an invalid source parameter. Valid options: ' + ALL_SOURCES_JOINED); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
else { |
|
||||||
var types = sources.reduce(function(acc, source) { |
|
||||||
return acc.concat(sources_map[source]); |
|
||||||
}, []); |
|
||||||
|
|
||||||
clean.types.from_source = types; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
return messages; |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = sanitize; |
|
@ -0,0 +1,37 @@ |
|||||||
|
var _ = require( 'lodash' ); |
||||||
|
var type_mapping = require( '../helper/type_mapping' ); |
||||||
|
|
||||||
|
/* |
||||||
|
* This sanitiser depends on clean.layers and clean.sources |
||||||
|
* so it has to be run after those sanitisers have been run |
||||||
|
*/ |
||||||
|
function sanitize( raw, clean ){ |
||||||
|
var messages = { errors: [], warnings: [] }; |
||||||
|
|
||||||
|
var possible_errors = []; |
||||||
|
var at_least_one_valid_combination = false; |
||||||
|
|
||||||
|
if (clean.layers && clean.sources) { |
||||||
|
clean.sources.forEach(function(source) { |
||||||
|
var layers_for_source = type_mapping.layers_by_source[source]; |
||||||
|
clean.layers.forEach(function(layer) { |
||||||
|
if (_.includes(layers_for_source, layer)) { |
||||||
|
at_least_one_valid_combination = true; |
||||||
|
} else { |
||||||
|
var message = 'You have specified both the `sources` and `layers` ' + |
||||||
|
'parameters in a combination that will return no results: the ' + |
||||||
|
source + ' source has nothing in the ' + layer + ' layer'; |
||||||
|
possible_errors.push(message); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
if (!at_least_one_valid_combination) { |
||||||
|
messages.errors = possible_errors; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return messages; |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = sanitize; |
@ -1,84 +0,0 @@ |
|||||||
var adminFields = require('../../../helper/adminFields'); |
|
||||||
|
|
||||||
module.exports.tests = {}; |
|
||||||
|
|
||||||
module.exports.tests.interface = function(test, common) { |
|
||||||
test('validate fields', function(t) { |
|
||||||
t.assert(adminFields instanceof Function, 'adminFields is a function'); |
|
||||||
t.assert(adminFields() instanceof Array, 'adminFields() returns an array'); |
|
||||||
t.assert(adminFields().length > 0, 'adminFields array is not empty'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.tests.lookupExistance = function(test, common) { |
|
||||||
test('all expected fields in schema', function(t) { |
|
||||||
|
|
||||||
var expectedFields = [ |
|
||||||
'one', |
|
||||||
'two', |
|
||||||
'three', |
|
||||||
'four' |
|
||||||
]; |
|
||||||
var schema = { mappings: { _default_: { properties: {} } } }; |
|
||||||
|
|
||||||
// inject all expected fields into schema mock
|
|
||||||
expectedFields.forEach(function (field) { |
|
||||||
schema.mappings._default_.properties[field] = {}; |
|
||||||
}); |
|
||||||
|
|
||||||
var res = adminFields(schema, expectedFields); |
|
||||||
|
|
||||||
t.deepEquals(res, expectedFields, 'all expected fields are returned'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
|
|
||||||
test('some expected fields in schema', function(t) { |
|
||||||
|
|
||||||
var expectedFields = [ |
|
||||||
'one', |
|
||||||
'two', |
|
||||||
'three', |
|
||||||
'four' |
|
||||||
]; |
|
||||||
var schema = { mappings: { _default_: { properties: {} } } }; |
|
||||||
|
|
||||||
// inject only some of the expected fields into schema mock
|
|
||||||
expectedFields.slice(0, 3).forEach(function (field) { |
|
||||||
schema.mappings._default_.properties[field] = {}; |
|
||||||
}); |
|
||||||
|
|
||||||
var res = adminFields(schema, expectedFields); |
|
||||||
|
|
||||||
t.deepEquals(res, expectedFields.slice(0, 3), 'only matching expected fields are returned'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
|
|
||||||
test('no expected fields in schema', function(t) { |
|
||||||
|
|
||||||
var schema = { mappings: { _default_: { properties: { foo: {} } } } }; |
|
||||||
|
|
||||||
var logErrorCalled = false; |
|
||||||
var logger = { |
|
||||||
error: function () { |
|
||||||
logErrorCalled = true; |
|
||||||
}}; |
|
||||||
|
|
||||||
var res = adminFields(schema, undefined, logger); |
|
||||||
|
|
||||||
t.deepEquals(res, [], 'no admin fields found'); |
|
||||||
t.assert(logErrorCalled, 'log error called'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.all = function (tape, common) { |
|
||||||
|
|
||||||
function test(name, testFunction) { |
|
||||||
return tape('adminFields: ' + name, testFunction); |
|
||||||
} |
|
||||||
|
|
||||||
for( var testCase in module.exports.tests ){ |
|
||||||
module.exports.tests[testCase](test, common); |
|
||||||
} |
|
||||||
}; |
|
@ -0,0 +1,87 @@ |
|||||||
|
|
||||||
|
var generator = require('../../../helper/labelGenerator'); |
||||||
|
|
||||||
|
module.exports.tests = {}; |
||||||
|
|
||||||
|
module.exports.tests.interface = function(test, common) { |
||||||
|
test('interface', function(t) { |
||||||
|
t.equal(typeof generator, 'function', 'valid function'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// GBR street address
|
||||||
|
module.exports.tests.one_main_street_uk = function(test, common) { |
||||||
|
test('one main street uk', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': '1 Main St', |
||||||
|
'housenumber': '1', |
||||||
|
'street': 'Main St', |
||||||
|
'postalcode': 'BT77 0BG', |
||||||
|
'country_a': 'GBR', |
||||||
|
'country': 'United Kingdom', |
||||||
|
'region': 'Dungannon' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'1 Main St, Dungannon, United Kingdom'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// GBR venue
|
||||||
|
module.exports.tests.hackney_city_farm = function(test, common) { |
||||||
|
test('hackney city farm', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Hackney City Farm', |
||||||
|
'country_a': 'GBR', |
||||||
|
'country': 'United Kingdom', |
||||||
|
'region': 'Hackney', |
||||||
|
'county': 'Greater London', |
||||||
|
'locality': 'London', |
||||||
|
'neighbourhood': 'Haggerston' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Hackney City Farm, Haggerston, Greater London'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// GBR country
|
||||||
|
module.exports.tests.wales = function(test, common) { |
||||||
|
test('wales', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Wales', |
||||||
|
'country_a': 'GBR', |
||||||
|
'country': 'United Kingdom', |
||||||
|
'region': 'Wales' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Wales, United Kingdom'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// GBR macroregion
|
||||||
|
module.exports.tests.macroregion_trumps_region = function(test, common) { |
||||||
|
test('macroregion should trump region when none of neighbourhood, county, localadmin, locality are available', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Name', |
||||||
|
'country_a': 'GBR', |
||||||
|
'country': 'Country Name', |
||||||
|
'macroregion': 'Macroregion Name', |
||||||
|
'region': 'Region Name' |
||||||
|
}; |
||||||
|
|
||||||
|
t.equal(generator(doc), 'Name, Macroregion Name, Country Name'); |
||||||
|
t.end(); |
||||||
|
|
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.all = function (tape, common) { |
||||||
|
|
||||||
|
function test(name, testFunction) { |
||||||
|
return tape('label generator (GBR): ' + name, testFunction); |
||||||
|
} |
||||||
|
|
||||||
|
for( var testCase in module.exports.tests ){ |
||||||
|
module.exports.tests[testCase](test, common); |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,51 @@ |
|||||||
|
|
||||||
|
var generator = require('../../../helper/labelGenerator'); |
||||||
|
|
||||||
|
module.exports.tests = {}; |
||||||
|
|
||||||
|
module.exports.tests.interface = function(test, common) { |
||||||
|
test('interface', function(t) { |
||||||
|
t.equal(typeof generator, 'function', 'valid function'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// SGP region
|
||||||
|
module.exports.tests.north_west_singapore = function(test, common) { |
||||||
|
test('north west singapore', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'North West', |
||||||
|
'country_a': 'SGP', |
||||||
|
'country': 'Singapore', |
||||||
|
'region': 'North West' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'North West, Singapore'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// SGP venue
|
||||||
|
module.exports.tests.singapore_mcdonalds = function(test, common) { |
||||||
|
test('singapore_mcdonalds', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'McDonald\'s', |
||||||
|
'country_a': 'SGP', |
||||||
|
'country': 'Singapore', |
||||||
|
'region': 'Central Singapore', |
||||||
|
'locality': 'Singapore' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'McDonald\'s, Central Singapore, Singapore'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.all = function (tape, common) { |
||||||
|
|
||||||
|
function test(name, testFunction) { |
||||||
|
return tape('label generator: ' + name, testFunction); |
||||||
|
} |
||||||
|
|
||||||
|
for( var testCase in module.exports.tests ){ |
||||||
|
module.exports.tests[testCase](test, common); |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,53 @@ |
|||||||
|
|
||||||
|
var generator = require('../../../helper/labelGenerator'); |
||||||
|
|
||||||
|
module.exports.tests = {}; |
||||||
|
|
||||||
|
module.exports.tests.interface = function(test, common) { |
||||||
|
test('interface', function(t) { |
||||||
|
t.equal(typeof generator, 'function', 'valid function'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// SWE city
|
||||||
|
module.exports.tests.skane1 = function(test, common) { |
||||||
|
test('skåne 1', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Malmö', |
||||||
|
'country_a': 'SWE', |
||||||
|
'country': 'Sweden', |
||||||
|
'region': 'Skåne', |
||||||
|
'county': 'Malmö' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Malmö, Skåne, Sweden'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// SWE city
|
||||||
|
module.exports.tests.skane2 = function(test, common) { |
||||||
|
test('skåne 2', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Malmö', |
||||||
|
'country_a': 'SWE', |
||||||
|
'country': 'Sweden', |
||||||
|
'region': 'Skåne', |
||||||
|
'county': 'Malmö', |
||||||
|
'locality': 'Malmö' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Malmö, Skåne, Sweden'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.all = function (tape, common) { |
||||||
|
|
||||||
|
function test(name, testFunction) { |
||||||
|
return tape('label generator: ' + name, testFunction); |
||||||
|
} |
||||||
|
|
||||||
|
for( var testCase in module.exports.tests ){ |
||||||
|
module.exports.tests[testCase](test, common); |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,229 @@ |
|||||||
|
var generator = require('../../../helper/labelGenerator'); |
||||||
|
|
||||||
|
module.exports.tests = {}; |
||||||
|
|
||||||
|
module.exports.tests.interface = function(test, common) { |
||||||
|
test('interface', function(t) { |
||||||
|
t.equal(typeof generator, 'function', 'valid function'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.tests.localadmin = function(test, common) { |
||||||
|
test('localadmin should trump locality, neighbourhood, and county', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Default Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name', |
||||||
|
'region_a': 'Region Abbr', |
||||||
|
'county': 'County Name', |
||||||
|
'localadmin': 'LocalAdmin Name', |
||||||
|
'locality': 'Locality Name', |
||||||
|
'neighbourhood': 'Neighbourhood Name' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Default Name, LocalAdmin Name, Region Abbr, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.tests.locality = function(test, common) { |
||||||
|
test('locality should trump neighbourhood and county when localadmin not available', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Default Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name', |
||||||
|
'region_a': 'Region Abbr', |
||||||
|
'county': 'County Name', |
||||||
|
'locality': 'Locality Name', |
||||||
|
'neighbourhood': 'Neighbourhood Name' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Default Name, Locality Name, Region Abbr, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.tests.neighbourhood = function(test, common) { |
||||||
|
test('neighbourhood should trump county when neither localadmin nor locality', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Default Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name', |
||||||
|
'region_a': 'Region Abbr', |
||||||
|
'county': 'County Name', |
||||||
|
'neighbourhood': 'Neighbourhood Name' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Default Name, Neighbourhood Name, Region Abbr, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.tests.county = function(test, common) { |
||||||
|
test('county should be used when localadmin, locality, and neighbourhood are not available', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Default Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name', |
||||||
|
'region_a': 'Region Abbr', |
||||||
|
'county': 'County Name' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Default Name, County Name, Region Abbr, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.tests.region = function(test, common) { |
||||||
|
test('region should be used when region_a is not available', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Default Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Default Name, Region Name, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// USA geonames state
|
||||||
|
module.exports.tests.region_geonames = function(test, common) { |
||||||
|
test('default name should not be prepended when source=geonames and layer=region', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Region Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name', |
||||||
|
'region_a': 'Region Abbr', |
||||||
|
'source': 'geonames', |
||||||
|
'layer': 'region' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Region Name, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// USA whosonfirst state
|
||||||
|
module.exports.tests.region_whosonfirst = function(test, common) { |
||||||
|
test('default name should not be prepended when source=whosonfirst and layer=region', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Region Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name', |
||||||
|
'region_a': 'Region Abbr', |
||||||
|
'source': 'whosonfirst', |
||||||
|
'layer': 'region' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Region Name, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// USA non-geonames/whosonfirst state
|
||||||
|
module.exports.tests.region_other_source = function(test, common) { |
||||||
|
test('default name should be prepended when layer=region and source is not whosonfirst or geonames', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Default Name', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'Region Name', |
||||||
|
'region_a': 'Region Abbr', |
||||||
|
'source': 'not geonames or whosonfirst', |
||||||
|
'layer': 'region' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Default Name, Region Name, USA',generator(doc)); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// major USA city
|
||||||
|
module.exports.tests.san_francisco = function(test, common) { |
||||||
|
test('san francisco', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'San Francisco', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'California', |
||||||
|
'region_a': 'CA', |
||||||
|
'county': 'San Francisco County', |
||||||
|
'locality': 'San Francisco' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'San Francisco, San Francisco County, CA, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// USA venue
|
||||||
|
module.exports.tests.nyc_office = function(test, common) { |
||||||
|
test('30 West 26th Street', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': '30 West 26th Street', |
||||||
|
'housenumber': '30', |
||||||
|
'street': 'West 26th Street', |
||||||
|
'postalcode': '10010', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'New York', |
||||||
|
'region_a': 'NY', |
||||||
|
'county': 'New York County', |
||||||
|
'localadmin': 'Manhattan', |
||||||
|
'locality': 'New York', |
||||||
|
'neighbourhood': 'Flatiron District' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'30 West 26th Street, Manhattan, NY, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// USA NYC eatery
|
||||||
|
module.exports.tests.nyc_bakery = function(test, common) { |
||||||
|
test('New York Bakery', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'New York Bakery', |
||||||
|
'housenumber': '51 W', |
||||||
|
'street': '29th', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'New York', |
||||||
|
'region_a': 'NY', |
||||||
|
'county': 'New York County', |
||||||
|
'localadmin': 'Manhattan', |
||||||
|
'locality': 'New York', |
||||||
|
'neighbourhood': 'Koreatown' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'New York Bakery, Manhattan, NY, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// USA SFC building
|
||||||
|
module.exports.tests.ferry_building = function(test, common) { |
||||||
|
test('Ferry Building', function(t) { |
||||||
|
var doc = { |
||||||
|
'name': 'Ferry Building', |
||||||
|
'country_a': 'USA', |
||||||
|
'country': 'United States', |
||||||
|
'region': 'California', |
||||||
|
'region_a': 'CA', |
||||||
|
'county': 'San Francisco County', |
||||||
|
'locality': 'San Francisco', |
||||||
|
'neighbourhood': 'Financial District' |
||||||
|
}; |
||||||
|
t.equal(generator(doc),'Ferry Building, San Francisco, CA, USA'); |
||||||
|
t.end(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports.all = function (tape, common) { |
||||||
|
|
||||||
|
function test(name, testFunction) { |
||||||
|
return tape('label generator: ' + name, testFunction); |
||||||
|
} |
||||||
|
|
||||||
|
for( var testCase in module.exports.tests ){ |
||||||
|
module.exports.tests[testCase](test, common); |
||||||
|
} |
||||||
|
}; |
@ -1,92 +0,0 @@ |
|||||||
var types = require('../../../helper/types'); |
|
||||||
|
|
||||||
module.exports.tests = {}; |
|
||||||
|
|
||||||
module.exports.tests.no_cleaned_types = function(test, common) { |
|
||||||
test('no cleaned types', function(t) { |
|
||||||
function testIt() { |
|
||||||
types({}); |
|
||||||
} |
|
||||||
|
|
||||||
t.throws(testIt, /clean_types should not be null or undefined/, 'no input should result in exception'); |
|
||||||
|
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.tests.address_parser = function(test, common) { |
|
||||||
test('address parser specifies only admin layers', function(t) { |
|
||||||
var cleaned_types = { |
|
||||||
from_text_parser: ['admin0'] // simplified return value from address parser
|
|
||||||
}; |
|
||||||
var actual = types(cleaned_types); |
|
||||||
var expected = ['admin0']; // simplified expected value for all admin layers
|
|
||||||
t.deepEqual(actual, expected, 'only layers specified by address parser returned'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.tests.layers_parameter = function(test, common) { |
|
||||||
test('layers parameter specifies only some layers', function(t) { |
|
||||||
var cleaned_types = { |
|
||||||
from_layers: ['geoname'] |
|
||||||
}; |
|
||||||
var actual = types(cleaned_types); |
|
||||||
var expected = ['geoname']; |
|
||||||
t.deepEqual(actual, expected, 'only types specified by layers parameter returned'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.tests.layers_parameter_and_address_parser = function(test, common) { |
|
||||||
test('layers parameter and address parser present', function(t) { |
|
||||||
var cleaned_types = { |
|
||||||
from_layers: ['geoname'], |
|
||||||
from_text_parser: ['admin0'] // simplified return value from address parse
|
|
||||||
}; |
|
||||||
var actual = types(cleaned_types); |
|
||||||
var expected = ['geoname']; |
|
||||||
t.deepEqual(actual, expected, 'layers parameter overrides address parser completely'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.tests.source_parameter = function(test, common) { |
|
||||||
test('source parameter specified', function(t) { |
|
||||||
var cleaned_types = { |
|
||||||
from_sources: ['openaddresses'] |
|
||||||
}; |
|
||||||
|
|
||||||
var actual = types(cleaned_types); |
|
||||||
|
|
||||||
var expected = ['openaddresses']; |
|
||||||
t.deepEqual(actual, expected, 'type parameter set to types specified by source'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.tests.source_and_layers_parameters = function(test, common) { |
|
||||||
test('source and layers parameter both specified', function(t) { |
|
||||||
var cleaned_types = { |
|
||||||
from_sources: ['openaddresses'], |
|
||||||
from_layers: ['osmaddress', 'openaddresses'] |
|
||||||
}; |
|
||||||
|
|
||||||
var actual = types(cleaned_types); |
|
||||||
|
|
||||||
var expected = ['openaddresses']; |
|
||||||
t.deepEqual(actual, expected, 'type set to intersection of source and layer types'); |
|
||||||
t.end(); |
|
||||||
}); |
|
||||||
}; |
|
||||||
|
|
||||||
module.exports.all = function (tape, common) { |
|
||||||
|
|
||||||
function test(name, testFunction) { |
|
||||||
return tape('types: ' + name, testFunction); |
|
||||||
} |
|
||||||
|
|
||||||
for( var testCase in module.exports.tests ){ |
|
||||||
module.exports.tests[testCase](test, common); |
|
||||||
} |
|
||||||
}; |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue