Skip to content

Commit

Permalink
refactor: Remove lodash dependencies (#1658)
Browse files Browse the repository at this point in the history
* Remove lodash dependencies

* Add tests and remove lodash from locks
  • Loading branch information
theruziev authored and TheSharpieOne committed Oct 14, 2019
1 parent a5f4882 commit b8a33f8
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 27 deletions.
3 changes: 0 additions & 3 deletions package.json
Expand Up @@ -101,9 +101,6 @@
"dependencies": {
"@babel/runtime": "^7.2.0",
"classnames": "^2.2.3",
"lodash.isfunction": "^3.0.9",
"lodash.isobject": "^3.0.2",
"lodash.tonumber": "^4.0.3",
"prop-types": "^15.5.8",
"react-lifecycles-compat": "^3.0.4",
"react-popper": "^1.3.3",
Expand Down
5 changes: 2 additions & 3 deletions src/Col.js
@@ -1,8 +1,7 @@
import isobject from 'lodash.isobject';
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { mapToCssModules, tagPropType } from './utils';
import { mapToCssModules, tagPropType, isObject } from './utils';

const colWidths = ['xs', 'sm', 'md', 'lg', 'xl'];
const stringOrNumberProp = PropTypes.oneOfType([PropTypes.number, PropTypes.string]);
Expand Down Expand Up @@ -66,7 +65,7 @@ const Col = (props) => {

const isXs = !i;

if (isobject(columnProp)) {
if (isObject(columnProp)) {
const colSizeInterfix = isXs ? '-' : `-${colWidth}-`;
const colClass = getColumnSizeClass(isXs, colWidth, columnProp.size);

Expand Down
5 changes: 2 additions & 3 deletions src/Label.js
@@ -1,8 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import isobject from 'lodash.isobject';
import { mapToCssModules, tagPropType } from './utils';
import { mapToCssModules, tagPropType, isObject } from './utils';

const colWidths = ['xs', 'sm', 'md', 'lg', 'xl'];

Expand Down Expand Up @@ -77,7 +76,7 @@ const Label = (props) => {
const isXs = !i;
let colClass;

if (isobject(columnProp)) {
if (isObject(columnProp)) {
const colSizeInterfix = isXs ? '-' : `-${colWidth}-`;
colClass = getColumnSizeClass(isXs, colWidth, columnProp.size);

Expand Down
3 changes: 1 addition & 2 deletions src/Progress.js
@@ -1,8 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import toNumber from 'lodash.tonumber';
import { mapToCssModules, tagPropType } from './utils';
import { mapToCssModules, tagPropType, toNumber } from './utils';

const propTypes = {
children: PropTypes.node,
Expand Down
80 changes: 80 additions & 0 deletions src/__tests__/utils.spec.js
Expand Up @@ -181,6 +181,86 @@ describe('Utils', () => {
});
});

describe('isFunction', function() {
it('should return `true` for functions', function() {
function test(){}
expect(Utils.isFunction(test)).toBe(true);
expect(Utils.isFunction(Array.prototype.slice)).toBe(true);
});

it('should return `true` for async functions', function() {
async function asyncFunc() {}
expect(Utils.isFunction(asyncFunc)).toEqual(typeof asyncFunc === 'function');
});

it('should return `true` for generator functions', function() {
function* genFunc() {}
expect(Utils.isFunction(genFunc)).toEqual(typeof genFunc === 'function');
});


it('should return `false` for non-functions', function() {
function toArgs(array) {
return (function() { return arguments; }.apply(undefined, array));
}
expect(Utils.isFunction(toArgs([1, 2, 3]))).toBe(false);
expect(Utils.isFunction([1, 2, 3])).toBe(false);
expect(Utils.isFunction(true)).toBe(false);
expect(Utils.isFunction(new Date)).toBe(false);
expect(Utils.isFunction(new Error)).toBe(false);
expect(Utils.isFunction({ 'a': 1 })).toBe(false);
expect(Utils.isFunction(1)).toBe(false);
expect(Utils.isFunction(/x/)).toBe(false);
expect(Utils.isFunction('a')).toBe(false);
expect(Utils.isFunction(Symbol("a"))).toBe(false);
//
if (document) {
expect(Utils.isFunction(document.getElementsByTagName('body'))).toBe(false);
}
});

});

describe('isObject', function() {
it('should return `true` for objects', function() {
function toArgs(array) {
return (function() { return arguments; }.apply(undefined, array));
}
expect(Utils.isObject([1, 2, 3])).toBe(true);
expect(Utils.isObject(Object(false))).toBe(true);
expect(Utils.isObject(new Date)).toBe(true);
expect(Utils.isObject(new Error)).toBe(true);
expect(Utils.isObject({ 'a': 1 })).toBe(true);
expect(Utils.isObject({ 'a': 1 })).toBe(true);
expect(Utils.isObject(Object(0))).toBe(true);
expect(Utils.isObject(/x/)).toBe(true);
expect(Utils.isObject(Object("a"))).toBe(true);
if (document) {
expect(Utils.isObject(document.body)).toBe(true);
}
});

it('should return `false` for non-objects', function() {

expect(Utils.isObject(0)).toBe(false);
expect(Utils.isObject(false)).toBe(false);
expect(Utils.isObject(1)).toBe(false);
});

});

describe('toNumber', function() {
it('should return number', function() {
expect(Utils.toNumber("5")).toEqual(5);
expect(Utils.toNumber("5.0")).toEqual(5);
expect(Utils.toNumber("1.1")).toEqual(1.1);
expect(Utils.toNumber("-1.1")).toEqual(-1.1);
expect(Utils.toNumber(0/0)).toEqual(NaN);
expect(Utils.toNumber(0)).toEqual(0);

});
});

// TODO
// describe('getScrollbarWidth', () => {
// // jsdom workaround https://github.com/tmpvar/jsdom/issues/135#issuecomment-68191941
Expand Down
46 changes: 45 additions & 1 deletion src/utils.js
@@ -1,4 +1,3 @@
import isFunction from 'lodash.isfunction';
import PropTypes from 'prop-types';

// https://github.com/twbs/bootstrap/blob/v4.0.0-alpha.4/js/src/modal.js#L436-L443
Expand Down Expand Up @@ -226,6 +225,51 @@ export function isReactRefObj(target) {
return false;
}

function getTag(value) {
if (value == null) {
return value === undefined ? '[object Undefined]' : '[object Null]'
}
return Object.prototype.toString.call(value)
}

export function toNumber(value) {
const type = typeof value;
const NAN = 0 / 0;
if (type === 'number') {
return value
}
if (type === 'symbol' || (type === 'object' && getTag(value) === '[object Symbol]')) {
return NAN
}
if (isObject(value)) {
const other = typeof value.valueOf === 'function' ? value.valueOf() : value;
value = isObject(other) ? `${other}` : other
}
if (type !== 'string') {
return value === 0 ? value : +value
}
value = value.replace(/^\s+|\s+$/g, '');
const isBinary = /^0b[01]+$/i.test(value);
return (isBinary || /^0o[0-7]+$/i.test(value))
? parseInt(value.slice(2), isBinary ? 2 : 8)
: (/^[-+]0x[0-9a-f]+$/i.test(value) ? NAN : +value)
}

export function isObject(value) {
const type = typeof value;
return value != null && (type === 'object' || type === 'function')
}

export function isFunction(value) {
if (!isObject(value)) {
return false
}

const tag = getTag(value);
return tag === '[object Function]' || tag === '[object AsyncFunction]' ||
tag === '[object GeneratorFunction]' || tag === '[object Proxy]'
}

export function findDOMElements(target) {
if (isReactRefObj(target)) {
return target.current;
Expand Down
15 changes: 0 additions & 15 deletions yarn.lock
Expand Up @@ -7821,21 +7821,11 @@ lodash.isequal@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=

lodash.isfunction@^3.0.9:
version "3.0.9"
resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051"
integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==

lodash.ismatch@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37"
integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=

lodash.isobject@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d"
integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=

lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
Expand Down Expand Up @@ -7915,11 +7905,6 @@ lodash.templatesettings@^4.0.0:
dependencies:
lodash._reinterpolate "^3.0.0"

lodash.tonumber@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz#0b96b31b35672793eb7f5a63ee791f1b9e9025d9"
integrity sha1-C5azGzVnJ5Prf1pj7nkfG56QJdk=

lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
Expand Down

0 comments on commit b8a33f8

Please sign in to comment.