From 4850b97143081fab74b4f0cad2a851d01da611bd Mon Sep 17 00:00:00 2001 From: Giora Guttsait Date: Mon, 25 Sep 2017 23:09:23 +0300 Subject: [PATCH] Refactor to reduce code repetition closes #5 --- index.js | 91 ++++++++++++++++++++++++-------------------------------- test.js | 24 ++++++++------- 2 files changed, 53 insertions(+), 62 deletions(-) diff --git a/index.js b/index.js index 2ba0ab3..f618e36 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ 'use strict'; const toString = Object.prototype.toString; const getObjectType = x => toString.call(x).slice(8, -1); +const isOfType = type => x => getObjectType(x) === type; const is = value => { if (value == null) { // eslint-disable-line no-eq-null, eqeqeq @@ -59,69 +60,55 @@ is.string = x => typeof x === 'string'; is.number = x => typeof x === 'number'; is.boolean = x => typeof x === 'boolean'; is.symbol = x => typeof x === 'symbol'; +is.nullOrUndefined = x => is.null(x) || is.undefined(x); + +const primitiveTypes = new Set([ + 'undefined', + 'string', + 'number', + 'boolean', + 'symbol' +]); +is.primitive = x => is.null(x) || primitiveTypes.has(typeof x); is.array = Array.isArray; is.function = x => typeof x === 'function'; is.buffer = Buffer.isBuffer; -is.object = x => { - const type = typeof x; - return x !== null && (type === 'object' || type === 'function'); -}; +is.object = x => !is.nullOrUndefined(x) && (is.function(x) || typeof x === 'object'); -is.nativePromise = x => getObjectType(x) === 'Promise'; +is.nativePromise = isOfType('Promise'); -is.promise = x => { - return is.nativePromise(x) || - ( - x !== null && - typeof x === 'object' && - typeof x.then === 'function' && - typeof x.catch === 'function' - ); -}; +const hasPromiseAPI = x => + !is.null(x) && + typeof x === 'object' && + is.function(x.then) && + is.function(x.catch); -is.regExp = x => getObjectType(x) === 'RegExp'; -is.date = x => getObjectType(x) === 'Date'; -is.error = x => getObjectType(x) === 'Error'; -is.map = x => getObjectType(x) === 'Map'; -is.set = x => getObjectType(x) === 'Set'; -is.weakMap = x => getObjectType(x) === 'WeakMap'; -is.weakSet = x => getObjectType(x) === 'WeakSet'; +is.promise = x => is.nativePromise(x) || hasPromiseAPI(x); -is.int8Array = x => getObjectType(x) === 'Int8Array'; -is.uint8Array = x => getObjectType(x) === 'Uint8Array'; -is.uint8ClampedArray = x => getObjectType(x) === 'Uint8ClampedArray'; -is.int16Array = x => getObjectType(x) === 'Int16Array'; -is.uint16Array = x => getObjectType(x) === 'Uint16Array'; -is.int32Array = x => getObjectType(x) === 'Int32Array'; -is.uint32Array = x => getObjectType(x) === 'Uint32Array'; -is.float32Array = x => getObjectType(x) === 'Float32Array'; -is.float64Array = x => getObjectType(x) === 'Float64Array'; +is.regExp = isOfType('RegExp'); +is.date = isOfType('Date'); +is.error = isOfType('Error'); +is.map = isOfType('Map'); +is.set = isOfType('Set'); +is.weakMap = isOfType('WeakMap'); +is.weakSet = isOfType('WeakSet'); -is.arrayBuffer = x => getObjectType(x) === 'ArrayBuffer'; +is.int8Array = isOfType('Int8Array'); +is.uint8Array = isOfType('Uint8Array'); +is.uint8ClampedArray = isOfType('Uint8ClampedArray'); +is.int16Array = isOfType('Int16Array'); +is.uint16Array = isOfType('Uint16Array'); +is.int32Array = isOfType('Int32Array'); +is.uint32Array = isOfType('Uint32Array'); +is.float32Array = isOfType('Float32Array'); +is.float64Array = isOfType('Float64Array'); -is.sharedArrayBuffer = x => { - try { - return getObjectType(x) === 'SharedArrayBuffer'; - } catch (err) { - return false; - } -}; +is.arrayBuffer = isOfType('ArrayBuffer'); +is.sharedArrayBuffer = isOfType('SharedArrayBuffer'); is.nan = Number.isNaN; -is.nullOrUndefined = x => x === null || typeof x === 'undefined'; - -is.primitive = x => { - const type = typeof x; - return x === null || - type === 'undefined' || - type === 'string' || - type === 'number' || - type === 'boolean' || - type === 'symbol'; -}; - is.integer = Number.isInteger; is.plainObject = x => { @@ -133,9 +120,9 @@ is.plainObject = x => { prototype === Object.getPrototypeOf({})); }; -is.iterable = x => !is.null(x) && !is.undefined(x) && typeof x[Symbol.iterator] === 'function'; +is.iterable = x => !is.nullOrUndefined(x) && is.function(x[Symbol.iterator]); -is.class = x => typeof x === 'function' && x.toString().startsWith('class '); +is.class = x => is.function(x) && x.toString().startsWith('class '); const typedArrayTypes = new Set([ 'Int8Array', diff --git a/test.js b/test.js index 18f6158..e40d076 100644 --- a/test.js +++ b/test.js @@ -10,7 +10,11 @@ const ErrorSubclassFixture = class extends Error {}; const types = new Map([ ['undefined', undefined], ['null', null], - ['string', '🦄'], + ['string', [ + '🦄', + 'hello world', + '' + ]], ['number', [ 6, 1.4, @@ -247,9 +251,7 @@ test('is.primitive', t => { Symbol('🦄') ]; - for (const el of primitives) { - t.true(m.primitive(el)); - } + primitives.forEach(el => t.true(m.primitive(el))); }); test('is.integer', t => { @@ -320,13 +322,15 @@ test('is.inRange', t => { t.true(m.inRange(x, 10)); t.true(m.inRange(0, 0)); + t.true(m.inRange(-2, -3)); t.false(m.inRange(x, 2)); + t.false(m.inRange(-3, -2)); - t.throws(() => { - t.true(m.inRange(0)); - }); + t.throws(() => + t.true(m.inRange(0)) + ); - t.throws(() => { - t.true(m.inRange(0, [5])); - }); + t.throws(() => + t.true(m.inRange(0, [5])) + ); });