From 6f1e6894991f848caf3d00d770992f4daacbc34b Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 29 Aug 2017 00:29:20 -0400 Subject: [PATCH 1/2] Add isNumber & improve type checking for @turf/helpers --- packages/turf-helpers/bench.js | 2 +- packages/turf-helpers/index.d.ts | 5 +++++ packages/turf-helpers/index.js | 21 ++++++++++++++++++- packages/turf-helpers/test.js | 35 +++++++++++++++++++++++++++++++- packages/turf-helpers/types.ts | 25 +++++++++++++++++++++++ packages/turf/index.d.ts | 6 ++++-- packages/turf/index.js | 1 + packages/turf/module.js | 6 ++++-- 8 files changed, 94 insertions(+), 7 deletions(-) diff --git a/packages/turf-helpers/bench.js b/packages/turf-helpers/bench.js index 76b9c93667..6b781326c9 100644 --- a/packages/turf-helpers/bench.js +++ b/packages/turf-helpers/bench.js @@ -20,8 +20,8 @@ const { */ const suite = new Benchmark.Suite('turf-helpers'); suite - .add('round', () => round(120.123)) .add('point', () => point([5, 10])) + .add('round', () => round(120.123)) .add('lineString', () => lineString([[5, 10], [20, 40]])) .add('polygon', () => polygon([[[5, 10], [20, 40], [40, 0], [5, 10]]])) .add('multiPoint', () => multiPoint([[0, 0], [10, 10]])) diff --git a/packages/turf-helpers/index.d.ts b/packages/turf-helpers/index.d.ts index 213b5a4e5b..e254235d4b 100644 --- a/packages/turf-helpers/index.d.ts +++ b/packages/turf-helpers/index.d.ts @@ -132,3 +132,8 @@ export function convertDistance(distance: number, originalUnit: Units, finalUnit * http://turfjs.org/docs/#convertarea */ export function convertArea(area: number, originalUnit?: Units, finalUnit?: Units): number + +/** + * http://turfjs.org/docs/#isnumber + */ +export function isNumber(num: any): boolean diff --git a/packages/turf-helpers/index.js b/packages/turf-helpers/index.js index 561faa8963..12178d894f 100644 --- a/packages/turf-helpers/index.js +++ b/packages/turf-helpers/index.js @@ -87,6 +87,7 @@ function point(coordinates, properties, bbox, id) { if (!coordinates) throw new Error('No coordinates passed'); if (coordinates.length === undefined) throw new Error('Coordinates must be an array'); if (coordinates.length < 2) throw new Error('Coordinates must be at least 2 numbers long'); + if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) throw new Error('Coordinates must contain numbers'); return feature({ type: 'Point', @@ -125,6 +126,7 @@ function polygon(coordinates, properties, bbox, id) { throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.'); } for (var j = 0; j < ring[ring.length - 1].length; j++) { + if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('Coordinates must contain numbers'); if (ring[ring.length - 1][j] !== ring[0][j]) { throw new Error('First and last Position are not equivalent.'); } @@ -169,6 +171,7 @@ function polygon(coordinates, properties, bbox, id) { function lineString(coordinates, properties, bbox, id) { if (!coordinates) throw new Error('No coordinates passed'); if (coordinates.length < 2) throw new Error('Coordinates must be an array of two or more positions'); + if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('Coordinates must contain numbers'); return feature({ type: 'LineString', @@ -497,6 +500,21 @@ function convertArea(area, originalUnit, finalUnit) { return (area / startFactor) * finalFactor; } +/** + * isNumber + * + * @param {*} num Number to validate + * @returns {boolean} true/false + * @example + * turf.isNumber(123) + * //=true + * turf.isNumber('foo') + * //=false + */ +function isNumber(num) { + return !isNaN(num) && num !== null && !Array.isArray(num); +} + module.exports = { feature: feature, geometry: geometry, @@ -516,5 +534,6 @@ module.exports = { bearingToAngle: bearingToAngle, convertDistance: convertDistance, convertArea: convertArea, - round: round + round: round, + isNumber: isNumber }; diff --git a/packages/turf-helpers/test.js b/packages/turf-helpers/test.js index a910824f7a..8848316d5d 100644 --- a/packages/turf-helpers/test.js +++ b/packages/turf-helpers/test.js @@ -17,7 +17,8 @@ const { bearingToAngle, convertDistance, convertArea, - round + round, + isNumber } = require('./'); test('point', t => { @@ -411,3 +412,35 @@ test('turf-helpers -- Handle Id & BBox properties', t => { t.throws(() => featureCollection([pt], [0], {invalid: 'id'}), 'throws invalid id'); t.end(); }); + +test('turf-helpers -- isNumber', t => { + t.throws(() => point(['foo', 'bar']), /Coordinates must contain numbers/, 'Coordinates must contain numbers'); + t.throws(() => lineString([['foo', 'bar'], ['hello', 'world']]), /Coordinates must contain numbers/, 'Coordinates must contain numbers'); + t.throws(() => polygon([[['foo', 'bar'], ['hello', 'world'], ['world', 'hello'], ['foo', 'bar']]]), /Coordinates must contain numbers/, 'Coordinates must contain numbers'); + + // true + t.true(isNumber(123)); + t.true(isNumber(1.23)); + t.true(isNumber(-1.23)); + t.true(isNumber(-123)); + t.true(isNumber('123')); + t.true(isNumber(+'123')); + t.true(isNumber('1e10000')); + t.true(isNumber(1e10000)); + t.true(isNumber(Infinity)); + t.true(isNumber(-Infinity)); + + // false + t.false(isNumber(+'ciao')); + t.false(isNumber('foo')); + t.false(isNumber('10px')); + t.false(isNumber(NaN)); + t.false(isNumber(undefined)); + t.false(isNumber(null)); + t.false(isNumber({a: 1})); + t.false(isNumber({})); + t.false(isNumber([1, 2, 3])); + t.false(isNumber([])); + t.false(isNumber(isNumber)); + t.end(); +}); diff --git a/packages/turf-helpers/types.ts b/packages/turf-helpers/types.ts index 44d2586caf..efebbd8854 100644 --- a/packages/turf-helpers/types.ts +++ b/packages/turf-helpers/types.ts @@ -59,3 +59,28 @@ helpers.geometryCollection([pt.geometry], properties, bbox, 1) helpers.point(pt.geometry.coordinates, {foo: 'bar'}) helpers.point(pt.geometry.coordinates, {1: 2}) helpers.point(pt.geometry.coordinates, {1: {foo: 'bar'}}) + +// isNumber -- true +helpers.isNumber(123) +helpers.isNumber(1.23) +helpers.isNumber(-1.23) +helpers.isNumber(-123) +helpers.isNumber('123') +helpers.isNumber(+'123') +helpers.isNumber('1e10000') +helpers.isNumber(1e10000) +helpers.isNumber(Infinity) +helpers.isNumber(-Infinity) + +// isNumber -- false +helpers.isNumber(+'ciao') +helpers.isNumber('foo') +helpers.isNumber('10px') +helpers.isNumber(NaN) +helpers.isNumber(undefined) +helpers.isNumber(null) +helpers.isNumber({a: 1}) +helpers.isNumber({}) +helpers.isNumber([1, 2, 3]) +helpers.isNumber([]) +helpers.isNumber(helpers.isNumber) diff --git a/packages/turf/index.d.ts b/packages/turf/index.d.ts index f5563a6874..f41f4835e3 100644 --- a/packages/turf/index.d.ts +++ b/packages/turf/index.d.ts @@ -17,7 +17,8 @@ import { degrees2radians, round, convertDistance, - convertArea} from '@turf/helpers'; + convertArea, + isNumber} from '@turf/helpers'; import { getGeom, getGeomType, @@ -243,5 +244,6 @@ export { clone, segmentEach, segmentReduce, - cleanCoords + cleanCoords, + isNumber }; diff --git a/packages/turf/index.js b/packages/turf/index.js index b8086edd2a..417e9e25af 100644 --- a/packages/turf/index.js +++ b/packages/turf/index.js @@ -119,6 +119,7 @@ var turf = { degrees2radians: helpers.degrees2radians, radians2degrees: helpers.radians2degrees, convertDistance: helpers.convertDistance, + isNumber: helpers.isNumber, // 4.7.0 round: helpers.round, convertArea: helpers.convertArea, getCoord: invariant.getCoord, diff --git a/packages/turf/module.js b/packages/turf/module.js index f5563a6874..f41f4835e3 100644 --- a/packages/turf/module.js +++ b/packages/turf/module.js @@ -17,7 +17,8 @@ import { degrees2radians, round, convertDistance, - convertArea} from '@turf/helpers'; + convertArea, + isNumber} from '@turf/helpers'; import { getGeom, getGeomType, @@ -243,5 +244,6 @@ export { clone, segmentEach, segmentReduce, - cleanCoords + cleanCoords, + isNumber }; From b93fe9b174abd77ef655dbfcf5529e05e71316c7 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 29 Aug 2017 02:37:30 -0400 Subject: [PATCH 2/2] Add comment to isNumber type checking --- packages/turf-helpers/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/turf-helpers/index.js b/packages/turf-helpers/index.js index 12178d894f..7fb1392235 100644 --- a/packages/turf-helpers/index.js +++ b/packages/turf-helpers/index.js @@ -126,6 +126,7 @@ function polygon(coordinates, properties, bbox, id) { throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.'); } for (var j = 0; j < ring[ring.length - 1].length; j++) { + // Check if first point of Polygon contains two numbers if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('Coordinates must contain numbers'); if (ring[ring.length - 1][j] !== ring[0][j]) { throw new Error('First and last Position are not equivalent.'); @@ -171,6 +172,7 @@ function polygon(coordinates, properties, bbox, id) { function lineString(coordinates, properties, bbox, id) { if (!coordinates) throw new Error('No coordinates passed'); if (coordinates.length < 2) throw new Error('Coordinates must be an array of two or more positions'); + // Check if first point of LineString contains two numbers if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('Coordinates must contain numbers'); return feature({