Add emptiness methods (#61)

Fix #53
This commit is contained in:
Arfat Salman 2018-09-28 11:54:35 +05:30 committed by Sindre Sorhus
parent 65c94f1a02
commit 6e07df5896
3 changed files with 169 additions and 51 deletions

View file

@ -160,6 +160,68 @@ is.boundFunction(function () {});
##### .sharedArrayBuffer(value)
##### .dataView(value)
#### Emptiness
##### .emptyString(value)
Returns `true` if the value is a `string` and the `.length` is 0.
##### .nonEmptyString(value)
Returns `true` if the value is a `string` and the `.length` is more than 0.
##### .emptyStringOrWhitespace(value)
Returns `true` if `is.emptyString(value)` or if it's a `string` that is all whitespace.
##### .emptyArray(value)
Returns `true` if the value is an `Array` and the `.length` is 0.
##### .nonEmptyArray(value)
Returns `true` if the value is an `Array` and the `.length` is more than 0.
##### .emptyObject(value)
Returns `true` if the value is an `Object` and `Object.keys(value).length` is 0.
Please note that `Object.keys` returns only own enumerable properties. Hence something like this can happen:
```js
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: true,
enumerable: false,
configurable: true
});
is.emptyObject(object1);
// => true
```
##### .nonEmptyObject(value)
Returns `true` if the value is an `Object` and `Object.keys(value).length` is more than 0.
##### .emptySet(value)
Returns `true` if the value is a `Set` and the `.size` is 0.
##### .nonEmptySet(Value)
Returns `true` if the value is a `Set` and the `.size` is more than 0.
##### .emptyMap(value)
Returns `true` if the value is a `Map` and the `.size` is 0.
##### .nonEmptyMap(value)
Returns `true` if the value is a `Map` and the `.size` is more than 0.
#### Miscellaneous
##### .directInstanceOf(value, class)
@ -295,14 +357,6 @@ Returns `true` if `value` is an even integer.
Returns `true` if `value` is an odd integer.
##### .empty(value)
Returns `true` if `value` is falsy or an empty string, array, object, map, or set.
##### .emptyOrWhitespace(value)
Returns `true` if `is.empty(value)` or a string that is all whitespace.
##### .any(predicate, ...values)
Returns `true` if **any** of the input `values` returns true in the `predicate`:

View file

@ -270,12 +270,22 @@ namespace is { // tslint:disable-line:no-namespace
export const odd = isAbsoluteMod2(1);
const isWhiteSpaceString = (value: any) => string(value) && /\S/.test(value) === false;
const isEmptyStringOrArray = (value: any) => (string(value) || array(value)) && value.length === 0;
const isEmptyObject = (value: any) => !map(value) && !set(value) && object(value) && Object.keys(value).length === 0;
const isEmptyMapOrSet = (value: any) => (map(value) || set(value)) && value.size === 0;
export const empty = (value: any) => falsy(value) || isEmptyStringOrArray(value) || isEmptyObject(value) || isEmptyMapOrSet(value);
export const emptyOrWhitespace = (value: any) => empty(value) || isWhiteSpaceString(value);
export const emptyArray = (value: any) => array(value) && value.length === 0;
export const nonEmptyArray = (value: any) => array(value) && value.length > 0;
export const emptyString = (value: any) => string(value) && value.length === 0;
export const nonEmptyString = (value: any) => string(value) && value.length > 0;
export const emptyStringOrWhitespace = (value: any) => emptyString(value) || isWhiteSpaceString(value);
export const emptyObject = (value: any) => object(value) && !map(value) && !set(value) && Object.keys(value).length === 0;
export const nonEmptyObject = (value: any) => object(value) && !map(value) && !set(value) && Object.keys(value).length > 0;
export const emptySet = (value: any) => set(value) && value.size === 0;
export const nonEmptySet = (value: any) => set(value) && value.size > 0;
export const emptyMap = (value: any) => map(value) && value.size === 0;
export const nonEmptyMap = (value: any) => map(value) && value.size > 0;
type ArrayMethod = (fn: (value: any, index: number, array: any[]) => boolean, thisArg?: any) => boolean;
const predicateOnArray = (method: ArrayMethod, predicate: any, values: any[]) => {

View file

@ -46,6 +46,13 @@ const types = new Map<string, Test>([
''
]
}],
['emptyString', {
is: m.emptyString,
fixtures: [
'',
String()
]
}],
['number', {
is: m.number,
fixtures: [
@ -76,6 +83,13 @@ const types = new Map<string, Test>([
new Array(2) // tslint:disable-line:prefer-array-literal
]
}],
['emptyArray', {
is: m.emptyArray,
fixtures: [
[],
new Array()
]
}],
['function', {
is: m.function_,
fixtures: [
@ -167,13 +181,25 @@ const types = new Map<string, Test>([
['map', {
is: m.map,
fixtures: [
new Map()
new Map([['one', '1']]),
]
}],
['emptyMap', {
is: m.emptyMap,
fixtures: [
new Map(),
]
}],
['set', {
is: m.set,
fixtures: [
new Set()
new Set(['one'])
]
}],
['emptySet', {
is: m.emptySet,
fixtures: [
new Set(),
]
}],
['weakSet', {
@ -385,7 +411,7 @@ test('is.null', t => {
});
test('is.string', t => {
testType(t, 'string');
testType(t, 'string', ['emptyString']);
});
test('is.number', t => {
@ -401,7 +427,7 @@ test('is.symbol', t => {
});
test('is.array', t => {
testType(t, 'array');
testType(t, 'array', ['emptyArray']);
});
test('is.function', t => {
@ -465,11 +491,11 @@ test('is.generatorFunction', t => {
});
test('is.map', t => {
testType(t, 'map');
testType(t, 'map', ['emptyMap']);
});
test('is.set', t => {
testType(t, 'set');
testType(t, 'set', ['emptySet']);
});
test('is.weakMap', t => {
@ -739,40 +765,68 @@ test('is.odd', t => {
}
});
test('is.empty', t => {
t.true(m.empty(null));
t.true(m.empty(undefined));
t.true(m.empty(false));
t.false(m.empty(true));
t.true(m.empty(''));
t.false(m.empty('🦄'));
t.true(m.empty([]));
t.false(m.empty(['🦄']));
t.true(m.empty({}));
t.false(m.empty({unicorn: '🦄'}));
const tempMap = new Map();
t.true(m.empty(tempMap));
tempMap.set('unicorn', '🦄');
t.false(m.empty(tempMap));
const tempSet = new Set();
t.true(m.empty(tempSet));
tempSet.add(1);
t.false(m.empty(tempSet));
test('is.emptyArray', t => {
testType(t, 'emptyArray');
});
test('is.emptyOrWhitespace', t => {
t.true(m.emptyOrWhitespace(''));
t.true(m.emptyOrWhitespace(' '));
t.false(m.emptyOrWhitespace('🦄'));
t.false(m.emptyOrWhitespace('unicorn'));
test('is.nonEmptyArray', t => {
t.true(m.nonEmptyArray([1, 2, 3]));
t.false(m.nonEmptyArray([]));
t.false(m.nonEmptyArray(new Array()));
});
test('is.emptyString', t => {
testType(t, 'emptyString', ['string']);
t.false(m.emptyString('🦄'));
});
test('is.nonEmptyString', t => {
t.false(m.nonEmptyString(''));
t.false(m.nonEmptyString(String()));
t.true(m.nonEmptyString('🦄'));
});
test('is.emptyStringOrWhitespace', t => {
testType(t, 'emptyString', ['string']);
t.true(m.emptyStringOrWhitespace(' '));
t.false(m.emptyStringOrWhitespace('🦄'));
t.false(m.emptyStringOrWhitespace('unicorn'));
});
test('is.emptyObject', t => {
t.true(m.emptyObject({}));
t.true(m.emptyObject(new Object()));
t.false(m.emptyObject({unicorn: '🦄'}));
});
test('is.nonEmptyObject', t => {
t.false(m.nonEmptyObject({}));
t.false(m.nonEmptyObject(new Object()));
t.true(m.nonEmptyObject({unicorn: '🦄'}));
});
test('is.emptySet', t => {
testType(t, 'emptySet');
});
test('is.nonEmptySet', t => {
const tempSet = new Set();
t.false(m.nonEmptySet(tempSet));
tempSet.add(1);
t.true(m.nonEmptySet(tempSet));
});
test('is.emptyMap', t => {
testType(t, 'emptyMap');
});
test('is.nonEmptyMap', t => {
const tempMap = new Map();
t.false(m.nonEmptyMap(tempMap));
tempMap.set('unicorn', '🦄');
t.true(m.nonEmptyMap(tempMap));
});
test('is.any', t => {