From 0b5172a4525fbec97f8c27905be08814cbdf885a Mon Sep 17 00:00:00 2001 From: Stephen Hess Date: Wed, 16 Sep 2015 16:54:36 -0400 Subject: [PATCH 1/7] initial stab at confidence score calculation based on distance from point.lat and point.lon --- middleware/confidenceScoreReverse.js | 60 ++++++ routes/v1.js | 5 +- .../unit/middleware/confidenceScoreReverse.js | 185 ++++++++++++++++++ test/unit/run.js | 1 + 4 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 middleware/confidenceScoreReverse.js create mode 100644 test/unit/middleware/confidenceScoreReverse.js diff --git a/middleware/confidenceScoreReverse.js b/middleware/confidenceScoreReverse.js new file mode 100644 index 00000000..46e188f1 --- /dev/null +++ b/middleware/confidenceScoreReverse.js @@ -0,0 +1,60 @@ +var logger = require('pelias-logger').get('api'); +var _ = require('lodash'); + +// these are subjective terms, but wanted to add shortcuts to denote something +// about importance +var confidence = { + exact: 1.0, + excellent: 0.9, + good: 0.8, + okay: 0.7, + poor: 0.6, + none: 0.5 +}; + +function setup(peliasConfig) { + return computeScores; +} + +function computeScores(req, res, next) { + // do nothing if no result data set + if (!req.results || !req.results.data) { + return next(); + } + + // loop through data items and determine confidence scores + req.results.data = req.results.data.map(computeConfidenceScore.bind(null, req)); + + next(); +} + +function computeConfidenceScore(req, hit) { + // non-number or invalid distance should be given confidence 0.0 + if (typeof hit.distance !== 'number' || hit.distance < 0) { + hit.confidence = 0.0; + return hit; + } + + var meters = hit.distance * 1000; + + // figure out which range the distance lies in and assign confidence accordingly + // TODO: this could probably be made more node-y with a map of function->number + if (meters === 0) { + hit.confidence = confidence.exact; + } else if (_.inRange(meters, 0, 10)) { + hit.confidence = confidence.excellent; + } else if (_.inRange(meters, 10, 100)) { + hit.confidence = confidence.good; + } else if (_.inRange(meters, 100, 250)) { + hit.confidence = confidence.okay; + } else if (_.inRange(meters, 250, 1000)) { + hit.confidence = confidence.poor; + } else { + hit.confidence = confidence.none; + } + + return hit; + +} + +module.exports = setup; diff --git a/routes/v1.js b/routes/v1.js index 97ddcc0b..6bc72183 100644 --- a/routes/v1.js +++ b/routes/v1.js @@ -29,6 +29,7 @@ var controllers = { var postProc = { distances: require('../middleware/distance'), confidenceScores: require('../middleware/confidenceScore'), + confidenceScoresReverse: require('../middleware/confidenceScoreReverse'), renamePlacenames: require('../middleware/renamePlacenames'), geocodeJSON: require('../middleware/geocodeJSON'), sendJSON: require('../middleware/sendJSON') @@ -73,8 +74,10 @@ function addRoutes(app, peliasConfig) { sanitisers.reverse.middleware, middleware.types, controllers.search(undefined, reverseQuery), - // TODO: add confidence scores postProc.distances(), + // reverse confidence scoring depends on distance from origin + // so it must be calculated first + postProc.confidenceScoresReverse(peliasConfig), postProc.renamePlacenames(), postProc.geocodeJSON(peliasConfig), postProc.sendJSON diff --git a/test/unit/middleware/confidenceScoreReverse.js b/test/unit/middleware/confidenceScoreReverse.js new file mode 100644 index 00000000..41a288b2 --- /dev/null +++ b/test/unit/middleware/confidenceScoreReverse.js @@ -0,0 +1,185 @@ +var confidenceScoreReverse = require('../../../middleware/confidenceScoreReverse')(); + +module.exports.tests = {}; + +module.exports.tests.confidenceScoreReverse = function(test, common) { + test('distance == 0m should be given score 1.0', function(t) { + var req = { + results: { + data: [ + { + distance: 0 + } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 1.0, 'score should be exact confidence'); + t.end(); + }); + + }); + + test('0m < distance < 10m should be given score 0.9', function(t) { + var req = { + results: { + data: [ + { + distance: 0.0001 + }, + { + distance: 0.0099 + } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 0.9, 'score should be excellent confidence'); + t.equal(req.results.data[1].confidence, 0.9, 'score should be excellent confidence'); + t.end(); + }); + + }); + + test('10m <= distance < 100m should be given score 0.8', function(t) { + var req = { + results: { + data: [ + { + distance: 0.010 + }, + { + distance: 0.099 + } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 0.8, 'score should be good confidence'); + t.equal(req.results.data[1].confidence, 0.8, 'score should be good confidence'); + t.end(); + }); + + }); + + test('100m <= distance < 250m should be given score 0.7', function(t) { + var req = { + results: { + data: [ + { + distance: 0.100 + }, + { + distance: 0.249 + } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 0.7, 'score should be okay confidence'); + t.equal(req.results.data[1].confidence, 0.7, 'score should be okay confidence'); + t.end(); + }); + + }); + + test('250m <= distance < 1000m should be given score 0.6', function(t) { + var req = { + results: { + data: [ + { + distance: 0.250 + }, + { + distance: 0.999 + } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 0.6, 'score should be poor confidence'); + t.equal(req.results.data[1].confidence, 0.6, 'score should be poor confidence'); + t.end(); + }); + + }); + + test('distance >= 1000m should be given score 0.5', function(t) { + var req = { + results: { + data: [ + { + distance: 1 + }, + { + distance: 2 + } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 0.5, 'score should be least confidence'); + t.equal(req.results.data[1].confidence, 0.5, 'score should be least confidence'); + t.end(); + }); + + }); + + test('distance < 0 (invalid) should be given score 0.0', function(t) { + var req = { + results: { + data: [ + { + distance: -0.0001 + } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 0.0, 'score should be 0.0 confidence'); + t.end(); + }); + + }); + + test('non-number-type (invalid) distance should be given score 0.0', function(t) { + var req = { + results: { + data: [ + {}, + { distance: [] }, + { distance: {} }, + { distance: 'this is not a number' } + ] + } + }; + + confidenceScoreReverse(req, null, function() { + t.equal(req.results.data[0].confidence, 0.0, 'score should be 0.0 confidence'); + t.equal(req.results.data[1].confidence, 0.0, 'score should be 0.0 confidence'); + t.equal(req.results.data[2].confidence, 0.0, 'score should be 0.0 confidence'); + t.equal(req.results.data[3].confidence, 0.0, 'score should be 0.0 confidence'); + t.end(); + }); + + }); + +}; + +module.exports.all = function (tape, common) { + + function test(name, testFunction) { + return tape('[middleware] confidenceScoreReverse: ' + name, testFunction); + } + + for( var testCase in module.exports.tests ){ + module.exports.tests[testCase](test, common); + } +}; diff --git a/test/unit/run.js b/test/unit/run.js index 3c24d0fb..f54b77f8 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -27,6 +27,7 @@ var tests = [ require('./helper/types'), require('./sanitiser/_geo_common'), require('./middleware/distance'), + require('./middleware/confidenceScoreReverse'), ]; tests.map(function(t) { From 58494779293665279e7bafd5034983a1906ac3af Mon Sep 17 00:00:00 2001 From: Stephen Hess Date: Wed, 16 Sep 2015 17:17:31 -0400 Subject: [PATCH 2/7] adjusted 'exact' confidence to be within 1 meter --- middleware/confidenceScoreReverse.js | 4 +- .../unit/middleware/confidenceScoreReverse.js | 55 ++++++------------- 2 files changed, 18 insertions(+), 41 deletions(-) diff --git a/middleware/confidenceScoreReverse.js b/middleware/confidenceScoreReverse.js index 46e188f1..c1c7da0b 100644 --- a/middleware/confidenceScoreReverse.js +++ b/middleware/confidenceScoreReverse.js @@ -39,9 +39,9 @@ function computeConfidenceScore(req, hit) { // figure out which range the distance lies in and assign confidence accordingly // TODO: this could probably be made more node-y with a map of function->number - if (meters === 0) { + if (meters < 1.0) { hit.confidence = confidence.exact; - } else if (_.inRange(meters, 0, 10)) { + } else if (_.inRange(meters, 1, 10)) { hit.confidence = confidence.excellent; } else if (_.inRange(meters, 10, 100)) { hit.confidence = confidence.good; diff --git a/test/unit/middleware/confidenceScoreReverse.js b/test/unit/middleware/confidenceScoreReverse.js index 41a288b2..ddd53400 100644 --- a/test/unit/middleware/confidenceScoreReverse.js +++ b/test/unit/middleware/confidenceScoreReverse.js @@ -3,34 +3,30 @@ var confidenceScoreReverse = require('../../../middleware/confidenceScoreReverse module.exports.tests = {}; module.exports.tests.confidenceScoreReverse = function(test, common) { - test('distance == 0m should be given score 1.0', function(t) { + test('0m <= distance < 1m should be given score 1.0', function(t) { var req = { results: { data: [ - { - distance: 0 - } + { distance: 0.0000 / 1000.0 }, + { distance: 0.9999 / 1000.0 } ] } }; confidenceScoreReverse(req, null, function() { t.equal(req.results.data[0].confidence, 1.0, 'score should be exact confidence'); + t.equal(req.results.data[1].confidence, 1.0, 'score should be exact confidence'); t.end(); }); }); - test('0m < distance < 10m should be given score 0.9', function(t) { + test('1m <= distance < 10m should be given score 0.9', function(t) { var req = { results: { data: [ - { - distance: 0.0001 - }, - { - distance: 0.0099 - } + { distance: 1.0000 / 1000.0 }, + { distance: 9.9999 / 1000.0 } ] } }; @@ -47,12 +43,8 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { var req = { results: { data: [ - { - distance: 0.010 - }, - { - distance: 0.099 - } + { distance: 10.0000 / 1000.0 }, + { distance: 99.9999 / 1000.0 } ] } }; @@ -69,12 +61,8 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { var req = { results: { data: [ - { - distance: 0.100 - }, - { - distance: 0.249 - } + { distance: 100.0000 / 1000.0 }, + { distance: 249.9999 / 1000.0 } ] } }; @@ -91,12 +79,8 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { var req = { results: { data: [ - { - distance: 0.250 - }, - { - distance: 0.999 - } + { distance: 250.0000 / 1000.0 }, + { distance: 999.9999 / 1000.0 } ] } }; @@ -113,12 +97,8 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { var req = { results: { data: [ - { - distance: 1 - }, - { - distance: 2 - } + { distance: 1000.0 / 1000.0 }, + { distance: 2000.0 / 1000.0 } ] } }; @@ -135,9 +115,7 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { var req = { results: { data: [ - { - distance: -0.0001 - } + { distance: -1.0000 / 1000.0 } ] } }; @@ -174,7 +152,6 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { }; module.exports.all = function (tape, common) { - function test(name, testFunction) { return tape('[middleware] confidenceScoreReverse: ' + name, testFunction); } From 8be249b701b10a1d9fdc0a30ecd81173763cc451 Mon Sep 17 00:00:00 2001 From: Stephen Hess Date: Wed, 16 Sep 2015 17:32:32 -0400 Subject: [PATCH 3/7] added helper variables for readability --- middleware/confidenceScoreReverse.js | 51 +++++++++++++++------------- routes/v1.js | 2 +- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/middleware/confidenceScoreReverse.js b/middleware/confidenceScoreReverse.js index c1c7da0b..aa29ad0c 100644 --- a/middleware/confidenceScoreReverse.js +++ b/middleware/confidenceScoreReverse.js @@ -3,16 +3,21 @@ var _ = require('lodash'); // these are subjective terms, but wanted to add shortcuts to denote something // about importance -var confidence = { - exact: 1.0, - excellent: 0.9, - good: 0.8, - okay: 0.7, - poor: 0.6, - none: 0.5 -}; - -function setup(peliasConfig) { +var EXACT = 1.0; +var EXCELLENT = 0.9; +var GOOD = 0.8; +var OKAY = 0.7; +var POOR = 0.6; +var NONE = 0.5; +var INVALID = 0.0; + +var _1_METER = 1; +var _10_METERS = 10; +var _100_METERS = 100; +var _250_METERS = 250; +var _1_KILOMETER = 1000; + +function setup() { return computeScores; } @@ -31,26 +36,26 @@ function computeScores(req, res, next) { function computeConfidenceScore(req, hit) { // non-number or invalid distance should be given confidence 0.0 if (typeof hit.distance !== 'number' || hit.distance < 0) { - hit.confidence = 0.0; + hit.confidence = INVALID; return hit; } - var meters = hit.distance * 1000; + var distance = hit.distance * 1000.0; // figure out which range the distance lies in and assign confidence accordingly // TODO: this could probably be made more node-y with a map of function->number - if (meters < 1.0) { - hit.confidence = confidence.exact; - } else if (_.inRange(meters, 1, 10)) { - hit.confidence = confidence.excellent; - } else if (_.inRange(meters, 10, 100)) { - hit.confidence = confidence.good; - } else if (_.inRange(meters, 100, 250)) { - hit.confidence = confidence.okay; - } else if (_.inRange(meters, 250, 1000)) { - hit.confidence = confidence.poor; + if (distance < _1_METER) { + hit.confidence = EXACT; + } else if (_.inRange(distance, _1_METER, _10_METERS)) { + hit.confidence = EXCELLENT; + } else if (_.inRange(distance, _10_METERS, _100_METERS)) { + hit.confidence = GOOD; + } else if (_.inRange(distance, _100_METERS, _250_METERS)) { + hit.confidence = OKAY; + } else if (_.inRange(distance, _250_METERS, _1_KILOMETER)) { + hit.confidence = POOR; } else { - hit.confidence = confidence.none; + hit.confidence = NONE; } return hit; diff --git a/routes/v1.js b/routes/v1.js index 6bc72183..3db635f0 100644 --- a/routes/v1.js +++ b/routes/v1.js @@ -77,7 +77,7 @@ function addRoutes(app, peliasConfig) { postProc.distances(), // reverse confidence scoring depends on distance from origin // so it must be calculated first - postProc.confidenceScoresReverse(peliasConfig), + postProc.confidenceScoresReverse(), postProc.renamePlacenames(), postProc.geocodeJSON(peliasConfig), postProc.sendJSON From d270ba71cbb4badc571f0dfb8c24e19df1518a12 Mon Sep 17 00:00:00 2001 From: Stephen Hess Date: Wed, 16 Sep 2015 20:57:23 -0400 Subject: [PATCH 4/7] added negative tests for req w/o results and req.results w/o data --- .../unit/middleware/confidenceScoreReverse.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/unit/middleware/confidenceScoreReverse.js b/test/unit/middleware/confidenceScoreReverse.js index ddd53400..bad7d93b 100644 --- a/test/unit/middleware/confidenceScoreReverse.js +++ b/test/unit/middleware/confidenceScoreReverse.js @@ -3,6 +3,38 @@ var confidenceScoreReverse = require('../../../middleware/confidenceScoreReverse module.exports.tests = {}; module.exports.tests.confidenceScoreReverse = function(test, common) { + test('req without results should not throw exception', function(t) { + var req = {}; + + try { + confidenceScoreReverse(req, null, function() {}); + } + catch (e) { + t.fail('an exception should not have been thrown'); + } + finally { + t.end(); + } + + }); + + test('req.results without data should not throw exception', function(t) { + var req = { + results: {} + }; + + try { + confidenceScoreReverse(req, null, function() {}); + } + catch (e) { + t.fail('an exception should not have been thrown'); + } + finally { + t.end(); + } + + }); + test('0m <= distance < 1m should be given score 1.0', function(t) { var req = { results: { From 0cc4ac33e30cce7fcd7bc37862ad83fdb0220627 Mon Sep 17 00:00:00 2001 From: Stephen Hess Date: Thu, 17 Sep 2015 09:07:59 -0400 Subject: [PATCH 5/7] switched to lodash for is-number validation, removed range operation since ordering of conditionals makes them redundant --- middleware/confidenceScoreReverse.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/middleware/confidenceScoreReverse.js b/middleware/confidenceScoreReverse.js index aa29ad0c..384f1aa1 100644 --- a/middleware/confidenceScoreReverse.js +++ b/middleware/confidenceScoreReverse.js @@ -35,7 +35,7 @@ function computeScores(req, res, next) { function computeConfidenceScore(req, hit) { // non-number or invalid distance should be given confidence 0.0 - if (typeof hit.distance !== 'number' || hit.distance < 0) { + if (!_.isFinite(hit.distance) || hit.distance < 0) { hit.confidence = INVALID; return hit; } @@ -43,16 +43,15 @@ function computeConfidenceScore(req, hit) { var distance = hit.distance * 1000.0; // figure out which range the distance lies in and assign confidence accordingly - // TODO: this could probably be made more node-y with a map of function->number if (distance < _1_METER) { hit.confidence = EXACT; - } else if (_.inRange(distance, _1_METER, _10_METERS)) { + } else if (distance < _10_METERS) { hit.confidence = EXCELLENT; - } else if (_.inRange(distance, _10_METERS, _100_METERS)) { + } else if (distance < _100_METERS) { hit.confidence = GOOD; - } else if (_.inRange(distance, _100_METERS, _250_METERS)) { + } else if (distance < _250_METERS) { hit.confidence = OKAY; - } else if (_.inRange(distance, _250_METERS, _1_KILOMETER)) { + } else if (distance < _1_KILOMETER) { hit.confidence = POOR; } else { hit.confidence = NONE; From f63533dd9ca49fb01fc9ede5a24ea2c6402267c3 Mon Sep 17 00:00:00 2001 From: Diana Shkolnikov Date: Thu, 17 Sep 2015 16:29:07 -0400 Subject: [PATCH 6/7] Switch to res.data instead of req.results.data --- middleware/confidenceScoreReverse.js | 58 ++++--- .../unit/middleware/confidenceScoreReverse.js | 160 ++++++++---------- 2 files changed, 103 insertions(+), 115 deletions(-) diff --git a/middleware/confidenceScoreReverse.js b/middleware/confidenceScoreReverse.js index 384f1aa1..462ea9d9 100644 --- a/middleware/confidenceScoreReverse.js +++ b/middleware/confidenceScoreReverse.js @@ -3,19 +3,23 @@ var _ = require('lodash'); // these are subjective terms, but wanted to add shortcuts to denote something // about importance -var EXACT = 1.0; -var EXCELLENT = 0.9; -var GOOD = 0.8; -var OKAY = 0.7; -var POOR = 0.6; -var NONE = 0.5; -var INVALID = 0.0; +var SCORES = { + EXACT: 1.0, + EXCELLENT: 0.9, + GOOD: 0.8, + OKAY: 0.7, + POOR: 0.6, + NONE: 0.5, + INVALID: 0.0 +}; -var _1_METER = 1; -var _10_METERS = 10; -var _100_METERS = 100; -var _250_METERS = 250; -var _1_KILOMETER = 1000; +var BUCKETS = { + _1_METER: 1, + _10_METERS: 10, + _100_METERS: 100, + _250_METERS: 250, + _1_KILOMETER: 1000 +}; function setup() { return computeScores; @@ -23,38 +27,38 @@ function setup() { function computeScores(req, res, next) { // do nothing if no result data set - if (!req.results || !req.results.data) { + if (!res.data || !res.data) { return next(); } // loop through data items and determine confidence scores - req.results.data = req.results.data.map(computeConfidenceScore.bind(null, req)); + res.data = res.data.map(computeConfidenceScore); next(); } -function computeConfidenceScore(req, hit) { +function computeConfidenceScore(hit) { // non-number or invalid distance should be given confidence 0.0 if (!_.isFinite(hit.distance) || hit.distance < 0) { - hit.confidence = INVALID; + hit.confidence = SCORES.INVALID; return hit; } var distance = hit.distance * 1000.0; // figure out which range the distance lies in and assign confidence accordingly - if (distance < _1_METER) { - hit.confidence = EXACT; - } else if (distance < _10_METERS) { - hit.confidence = EXCELLENT; - } else if (distance < _100_METERS) { - hit.confidence = GOOD; - } else if (distance < _250_METERS) { - hit.confidence = OKAY; - } else if (distance < _1_KILOMETER) { - hit.confidence = POOR; + if (distance < BUCKETS._1_METER) { + hit.confidence = SCORES.EXACT; + } else if (distance < BUCKETS._10_METERS) { + hit.confidence = SCORES.EXCELLENT; + } else if (distance < BUCKETS._100_METERS) { + hit.confidence = SCORES.GOOD; + } else if (distance < BUCKETS._250_METERS) { + hit.confidence = SCORES.OKAY; + } else if (distance < BUCKETS._1_KILOMETER) { + hit.confidence = SCORES.POOR; } else { - hit.confidence = NONE; + hit.confidence = SCORES.NONE; } return hit; diff --git a/test/unit/middleware/confidenceScoreReverse.js b/test/unit/middleware/confidenceScoreReverse.js index bad7d93b..450fd0db 100644 --- a/test/unit/middleware/confidenceScoreReverse.js +++ b/test/unit/middleware/confidenceScoreReverse.js @@ -3,11 +3,11 @@ var confidenceScoreReverse = require('../../../middleware/confidenceScoreReverse module.exports.tests = {}; module.exports.tests.confidenceScoreReverse = function(test, common) { - test('req without results should not throw exception', function(t) { - var req = {}; + test('res without results should not throw exception', function(t) { + var res = {}; try { - confidenceScoreReverse(req, null, function() {}); + confidenceScoreReverse(null, res, function() {}); } catch (e) { t.fail('an exception should not have been thrown'); @@ -18,13 +18,13 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { }); - test('req.results without data should not throw exception', function(t) { - var req = { + test('res.results without data should not throw exception', function(t) { + var res = { results: {} }; try { - confidenceScoreReverse(req, null, function() {}); + confidenceScoreReverse(null, res, function() {}); } catch (e) { t.fail('an exception should not have been thrown'); @@ -36,146 +36,130 @@ module.exports.tests.confidenceScoreReverse = function(test, common) { }); test('0m <= distance < 1m should be given score 1.0', function(t) { - var req = { - results: { - data: [ - { distance: 0.0000 / 1000.0 }, - { distance: 0.9999 / 1000.0 } - ] - } + var res = { + data: [ + { distance: 0.0000 / 1000.0 }, + { distance: 0.9999 / 1000.0 } + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 1.0, 'score should be exact confidence'); - t.equal(req.results.data[1].confidence, 1.0, 'score should be exact confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 1.0, 'score should be exact confidence'); + t.equal(res.data[1].confidence, 1.0, 'score should be exact confidence'); t.end(); }); }); test('1m <= distance < 10m should be given score 0.9', function(t) { - var req = { - results: { - data: [ - { distance: 1.0000 / 1000.0 }, - { distance: 9.9999 / 1000.0 } - ] - } + var res = { + data: [ + { distance: 1.0000 / 1000.0 }, + { distance: 9.9999 / 1000.0 } + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 0.9, 'score should be excellent confidence'); - t.equal(req.results.data[1].confidence, 0.9, 'score should be excellent confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 0.9, 'score should be excellent confidence'); + t.equal(res.data[1].confidence, 0.9, 'score should be excellent confidence'); t.end(); }); }); test('10m <= distance < 100m should be given score 0.8', function(t) { - var req = { - results: { - data: [ - { distance: 10.0000 / 1000.0 }, - { distance: 99.9999 / 1000.0 } - ] - } + var res = { + data: [ + { distance: 10.0000 / 1000.0 }, + { distance: 99.9999 / 1000.0 } + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 0.8, 'score should be good confidence'); - t.equal(req.results.data[1].confidence, 0.8, 'score should be good confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 0.8, 'score should be good confidence'); + t.equal(res.data[1].confidence, 0.8, 'score should be good confidence'); t.end(); }); }); test('100m <= distance < 250m should be given score 0.7', function(t) { - var req = { - results: { - data: [ - { distance: 100.0000 / 1000.0 }, - { distance: 249.9999 / 1000.0 } - ] - } + var res = { + data: [ + { distance: 100.0000 / 1000.0 }, + { distance: 249.9999 / 1000.0 } + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 0.7, 'score should be okay confidence'); - t.equal(req.results.data[1].confidence, 0.7, 'score should be okay confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 0.7, 'score should be okay confidence'); + t.equal(res.data[1].confidence, 0.7, 'score should be okay confidence'); t.end(); }); }); test('250m <= distance < 1000m should be given score 0.6', function(t) { - var req = { - results: { - data: [ - { distance: 250.0000 / 1000.0 }, - { distance: 999.9999 / 1000.0 } - ] - } + var res = { + data: [ + {distance: 250.0000 / 1000.0}, + {distance: 999.9999 / 1000.0} + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 0.6, 'score should be poor confidence'); - t.equal(req.results.data[1].confidence, 0.6, 'score should be poor confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 0.6, 'score should be poor confidence'); + t.equal(res.data[1].confidence, 0.6, 'score should be poor confidence'); t.end(); }); }); test('distance >= 1000m should be given score 0.5', function(t) { - var req = { - results: { - data: [ - { distance: 1000.0 / 1000.0 }, - { distance: 2000.0 / 1000.0 } - ] - } + var res = { + data: [ + {distance: 1000.0 / 1000.0}, + {distance: 2000.0 / 1000.0} + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 0.5, 'score should be least confidence'); - t.equal(req.results.data[1].confidence, 0.5, 'score should be least confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 0.5, 'score should be least confidence'); + t.equal(res.data[1].confidence, 0.5, 'score should be least confidence'); t.end(); }); }); test('distance < 0 (invalid) should be given score 0.0', function(t) { - var req = { - results: { - data: [ - { distance: -1.0000 / 1000.0 } - ] - } + var res = { + data: [ + { distance: -1.0000 / 1000.0 } + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 0.0, 'score should be 0.0 confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 0.0, 'score should be 0.0 confidence'); t.end(); }); }); test('non-number-type (invalid) distance should be given score 0.0', function(t) { - var req = { - results: { - data: [ - {}, - { distance: [] }, - { distance: {} }, - { distance: 'this is not a number' } - ] - } + var res = { + data: [ + {}, + {distance: []}, + {distance: {}}, + {distance: 'this is not a number'} + ] }; - confidenceScoreReverse(req, null, function() { - t.equal(req.results.data[0].confidence, 0.0, 'score should be 0.0 confidence'); - t.equal(req.results.data[1].confidence, 0.0, 'score should be 0.0 confidence'); - t.equal(req.results.data[2].confidence, 0.0, 'score should be 0.0 confidence'); - t.equal(req.results.data[3].confidence, 0.0, 'score should be 0.0 confidence'); + confidenceScoreReverse(null, res, function() { + t.equal(res.data[0].confidence, 0.0, 'score should be 0.0 confidence'); + t.equal(res.data[1].confidence, 0.0, 'score should be 0.0 confidence'); + t.equal(res.data[2].confidence, 0.0, 'score should be 0.0 confidence'); + t.equal(res.data[3].confidence, 0.0, 'score should be 0.0 confidence'); t.end(); }); From 537effa8bfb6abfe3c91e6919ae4a019ef51b97b Mon Sep 17 00:00:00 2001 From: Diana Shkolnikov Date: Thu, 17 Sep 2015 19:06:59 -0400 Subject: [PATCH 7/7] Fix distance calculation to use 'point.lat' instead of 'lat' --- middleware/distance.js | 11 +++++++++-- test/unit/middleware/distance.js | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/middleware/distance.js b/middleware/distance.js index 389b724b..eb1d7c21 100644 --- a/middleware/distance.js +++ b/middleware/distance.js @@ -1,4 +1,5 @@ var geolib = require('geolib'); +var check = require('check-types'); function setup() { @@ -13,14 +14,20 @@ function computeDistances(req, res, next) { return next(); } - if ( !(req.clean.hasOwnProperty('lat') && req.clean.hasOwnProperty('lon')) ) { + if (!(check.number(req.clean['point.lat']) && + check.number(req.clean['point.lon']))) { return next(); } + var point = { + latitude: req.clean['point.lat'], + longitude: req.clean['point.lon'] + }; + res.data.forEach(function (place) { // the result of getDistance is in meters, so convert to kilometers place.distance = geolib.getDistance( - { latitude: req.clean.lat, longitude: req.clean.lon }, + point, { latitude: place.center_point.lat, longitude: place.center_point.lon } ) / 1000; }); diff --git a/test/unit/middleware/distance.js b/test/unit/middleware/distance.js index 81cf6871..da868e45 100644 --- a/test/unit/middleware/distance.js +++ b/test/unit/middleware/distance.js @@ -6,8 +6,8 @@ module.exports.tests.computeDistance = function(test, common) { test('valid lat/lon and results', function(t) { var req = { clean: { - lat: 45, - lon: -77 + 'point.lat': 45, + 'point.lon': -77 } }; var res = {