diff --git a/comparators/emoji.js b/comparators/emoji.js new file mode 100644 index 0000000..4821c9c --- /dev/null +++ b/comparators/emoji.js @@ -0,0 +1,25 @@ +'use strict'; +const isNameKey = require('../lib/names.js').isNameKey; + +const isEmoji = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/; + +module.exports = emoji; + +/* + Contains an emoji in one of the name tags + @param {geojson} newVersion + @returns {object|false) returns the detected incident or false +*/ +function emoji(newVersion) { + if (!newVersion || !newVersion.properties) return false; + + const tags = newVersion.properties; + for (const tag in tags) { + if (!isNameKey(tag)) continue; + const name = tags[tag]; + if (isEmoji.test(name)) { + return {message: 'Found emoji in ' + tag}; + } + } + return false; +} diff --git a/index.js b/index.js index 1422fce..b5cc5e1 100755 --- a/index.js +++ b/index.js @@ -50,6 +50,7 @@ module.exports = { rare_critical_feature_created: wrapsync( require('./comparators/rare_critical_feature_created') ), + emoji: wrapsync(require('./comparators/emoji')), deprecated_construction_proposal_tag: wrapsync( require('./comparators/deprecated_construction_proposal_tag.js') ), diff --git a/lib/names.js b/lib/names.js new file mode 100644 index 0000000..5c50bb0 --- /dev/null +++ b/lib/names.js @@ -0,0 +1,20 @@ +'use strict'; +const namePattern = /^(int_|short_|)?(name|wikidata:labels)(:.*)?$/; +const isNameKey = key => namePattern.test(key); +const priorityLanguages = new Set(['en', 'es', 'de', 'fr', 'ru', 'zh']); + +function isPrioNameKey(key) { + if (key === 'name') return true; + if (!isNameKey(key)) return false; + const parts = key.split(':'); + if ( + (parts[0] === 'name' || + [parts[0], parts[1]].join(':') === 'wikidata:labels') && + !priorityLanguages.has(parts[parts.length - 1]) + ) + return false; + return true; +} + +exports.isPrioNameKey = isPrioNameKey; +exports.isNameKey = isNameKey; diff --git a/tests/fixtures/emoji.json b/tests/fixtures/emoji.json new file mode 100644 index 0000000..fbe89da --- /dev/null +++ b/tests/fixtures/emoji.json @@ -0,0 +1,50 @@ +{ + "compareFunction": "emoji", + "fixtures": [ + { + "description": "Finds Emoji", + "newVersion": { + "type": "Feature", + "properties": { "name": "'Give me some 💵'" } + }, + "oldVersion": null, + "expectedResult": { "message": "Found emoji in name" } + }, + { + "description": "Finds Emoji", + "newVersion": { + "type": "Feature", + "properties": { "name": "If all you have is a 🔨" } + }, + "oldVersion": null, + "expectedResult": { "message": "Found emoji in name" } + }, + { + "description": "Finds Emoji", + "newVersion": { + "type": "Feature", + "properties": { "name": "Emojis 😂 in OSM" } + }, + "oldVersion": null, + "expectedResult": { "message": "Found emoji in name" } + }, + { + "description": "Finds Emoji", + "newVersion": { + "type": "Feature", + "properties": { "name": "OSM 😈" } + }, + "oldVersion": null, + "expectedResult": { "message": "Found emoji in name" } + }, + { + "description": "No Emoji in name", + "newVersion": { + "type": "Feature", + "properties": { "name": "OSM does not need Emojis" } + }, + "oldVersion": null, + "expectedResult": false + } + ] +}