diff --git a/src/utils/__tests__/is-false.spec-d.ts b/src/utils/__tests__/is-false.spec-d.ts new file mode 100644 index 00000000..6609ffc1 --- /dev/null +++ b/src/utils/__tests__/is-false.spec-d.ts @@ -0,0 +1,12 @@ +/** + * @file Type Tests - isFalse + * @module tutils/utils/tests/unit-d/isFalse + */ + +import type testSubject from '../is-false' + +describe('unit-d:utils/isFalse', () => { + it('should guard false', () => { + expectTypeOf().guards.toEqualTypeOf() + }) +}) diff --git a/src/utils/__tests__/is-false.spec.ts b/src/utils/__tests__/is-false.spec.ts new file mode 100644 index 00000000..4e129e33 --- /dev/null +++ b/src/utils/__tests__/is-false.spec.ts @@ -0,0 +1,16 @@ +/** + * @file Unit Tests - isFalse + * @module tutils/utils/tests/unit/isFalse + */ + +import testSubject from '../is-false' + +describe('unit:utils/isFalse', () => { + it('should return false if value is not false', () => { + expect(testSubject(0)).to.be.false + }) + + it('should return true if value is false', () => { + expect(testSubject(false)).to.be.true + }) +}) diff --git a/src/utils/__tests__/is-falsy.spec-d.ts b/src/utils/__tests__/is-falsy.spec-d.ts new file mode 100644 index 00000000..3119a2c1 --- /dev/null +++ b/src/utils/__tests__/is-falsy.spec-d.ts @@ -0,0 +1,13 @@ +/** + * @file Type Tests - isFalsy + * @module tutils/utils/tests/unit-d/isFalsy + */ + +import type { Falsy } from '#src/types' +import type testSubject from '../is-falsy' + +describe('unit-d:utils/isFalsy', () => { + it('should guard Falsy', () => { + expectTypeOf().guards.toEqualTypeOf() + }) +}) diff --git a/src/utils/__tests__/is-falsy.spec.ts b/src/utils/__tests__/is-falsy.spec.ts new file mode 100644 index 00000000..59c5b734 --- /dev/null +++ b/src/utils/__tests__/is-falsy.spec.ts @@ -0,0 +1,38 @@ +/** + * @file Unit Tests - isFalsy + * @module tutils/utils/tests/unit/isFalsy + */ + +import VEHICLE from '#fixtures/vehicle' +import testSubject from '../is-falsy' + +describe('unit:utils/isFalsy', () => { + it('should return false if value is not falsy', () => { + // Arrange + const cases: Parameters[] = [ + [1], + [true], + [VEHICLE], + [() => 'hello, world'] + ] + + // Act + Expect + cases.forEach(([value]) => expect(testSubject(value)).to.be.false) + }) + + it('should return true if value is falsy', () => { + // Arrange + const cases: Parameters[] = [ + [0], + [0n], + [''], + [null], + [false], + [undefined], + [Number.NaN] + ] + + // Act + Expect + cases.forEach(([value]) => expect(testSubject(value)).to.be.true) + }) +}) diff --git a/src/utils/__tests__/is-nan.spec.ts b/src/utils/__tests__/is-nan.spec.ts new file mode 100644 index 00000000..f9b28feb --- /dev/null +++ b/src/utils/__tests__/is-nan.spec.ts @@ -0,0 +1,22 @@ +/** + * @file Unit Tests - isNaN + * @module tutils/utils/tests/unit/isNaN + */ + +import FLOAT from '#fixtures/float' +import INTEGER from '#fixtures/integer' +import testSubject from '../is-nan' + +describe('unit:utils/isNaN', () => { + it('should return false if value is not Number.NaN', () => { + // Arrange + const cases: Parameters[] = [[FLOAT], [INTEGER]] + + // Act + Expect + cases.forEach(([value]) => expect(testSubject(value)).to.be.false) + }) + + it('should return true if value is Number.NaN', () => { + expect(testSubject(Number.NaN)).to.be.true + }) +}) diff --git a/src/utils/__tests__/is-true.spec-d.ts b/src/utils/__tests__/is-true.spec-d.ts new file mode 100644 index 00000000..c7bfbc17 --- /dev/null +++ b/src/utils/__tests__/is-true.spec-d.ts @@ -0,0 +1,12 @@ +/** + * @file Type Tests - isTrue + * @module tutils/utils/tests/unit-d/isTrue + */ + +import type testSubject from '../is-true' + +describe('unit-d:utils/isTrue', () => { + it('should guard true', () => { + expectTypeOf().guards.toEqualTypeOf() + }) +}) diff --git a/src/utils/__tests__/is-true.spec.ts b/src/utils/__tests__/is-true.spec.ts new file mode 100644 index 00000000..61e49c7d --- /dev/null +++ b/src/utils/__tests__/is-true.spec.ts @@ -0,0 +1,16 @@ +/** + * @file Unit Tests - isTrue + * @module tutils/utils/tests/unit/isTrue + */ + +import testSubject from '../is-true' + +describe('unit:utils/isTrue', () => { + it('should return false if value is not true', () => { + expect(testSubject(1)).to.be.false + }) + + it('should return true if value is true', () => { + expect(testSubject(true)).to.be.true + }) +}) diff --git a/src/utils/includes.ts b/src/utils/includes.ts index 8aa244ed..5fed517a 100644 --- a/src/utils/includes.ts +++ b/src/utils/includes.ts @@ -3,14 +3,8 @@ * @module tutils/utils/includes */ -import type { - Fn, - IfString, - NIL, - Nilable, - NumberString, - PropertyKey -} from '#src/types' +import type { Fn, IfString, NIL, Nilable, PropertyKey } from '#src/types' +import cast from './cast' import equal from './equal' import isString from './is-string' @@ -25,26 +19,30 @@ import isString from './is-string' * items to unique keys. If provided, two items with the same identity key will * be considered equal. * + * @todo examples + * * @template T - Value to search * @template K - Identity key type * * @param {T} value - Value to search * @param {unknown} target - Search target - * @param {Nilable>} [identity] - Identity key function - * @param {number | undefined} [position=0] - Position to begin search - * @return {boolean} `true` if `data` includes `target` + * @param {Nilable>} [identity] - Identity key function + * @param {Nilable} [position] - Position to begin search + * @return {boolean} `true` if `value` includes `target` */ -function includes< +const includes = < T extends string | readonly unknown[], - K extends PropertyKey = NumberString + K extends PropertyKey = PropertyKey >( value: T, target: unknown, - identity?: IfString>>, - position: number | undefined = 0 -): boolean { + identity?: IfString>>, + position?: Nilable +): boolean => { + position ??= 0 + return isString(value) - ? value.includes(target as string, position) + ? value.includes(cast(target), position) : value.slice(position).some(item => equal(target, item, identity)) } diff --git a/src/utils/index.ts b/src/utils/index.ts index 13da928d..9bb348b5 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -35,12 +35,15 @@ export { default as isCapitalized } from './is-capitalized' export { default as isDate } from './is-date' export { default as isEmptyString } from './is-empty-string' export { default as isEmptyValue } from './is-empty-value' +export { default as isFalse } from './is-false' +export { default as isFalsy } from './is-falsy' export { default as isFloat } from './is-float' export { default as isFunction } from './is-function' export { default as isInteger } from './is-integer' export { default as isJsonPrimitive } from './is-json-primitive' export { default as isLowercase } from './is-lowercase' export { default as isMap } from './is-map' +export { default as isNaN } from './is-nan' export { default as isNIL } from './is-nil' export { default as isNodeEnv } from './is-node-env' export { default as isNull } from './is-null' @@ -54,6 +57,7 @@ export { default as isRegExp } from './is-reg-exp' export { default as isSet } from './is-set' export { default as isString } from './is-string' export { default as isSymbol } from './is-symbol' +export { default as isTrue } from './is-true' export { default as isUndefined } from './is-undefined' export { default as isUppercase } from './is-uppercase' export { default as keys } from './keys' diff --git a/src/utils/is-empty-value.ts b/src/utils/is-empty-value.ts index a12ffa05..50487c7a 100644 --- a/src/utils/is-empty-value.ts +++ b/src/utils/is-empty-value.ts @@ -8,10 +8,18 @@ import isEmptyString from './is-empty-string' import isNIL from './is-nil' /** - * Checks if `value` is an empty string, `null`, or `undefined`. + * Checks if `value` is an {@linkcode EmptyValue}. + * + * Empty values include: + * + * - `''` + * - `null` + * - `undefined` + * + * @todo examples * * @param {unknown} value - Value to check - * @return {value is EmptyValue} `true` if `value` is empty + * @return {value is EmptyValue} `true` if `value` is empty value */ const isEmptyValue = (value: unknown): value is EmptyValue => { return isEmptyString(value) || isNIL(value) diff --git a/src/utils/is-false.ts b/src/utils/is-false.ts new file mode 100644 index 00000000..d8c2ca2b --- /dev/null +++ b/src/utils/is-false.ts @@ -0,0 +1,18 @@ +/** + * @file Utilities - isFalse + * @module tutils/utils/isFalse + */ + +import equal from './equal' + +/** + * Checks if `value` is `false`. + * + * @todo examples + * + * @param {unknown} value - Value to check + * @return {value is false} `true` if `value` is `false` + */ +const isFalse = (value: unknown): value is false => equal(false, value) + +export default isFalse diff --git a/src/utils/is-falsy.ts b/src/utils/is-falsy.ts new file mode 100644 index 00000000..0ee5b1c4 --- /dev/null +++ b/src/utils/is-falsy.ts @@ -0,0 +1,39 @@ +/** + * @file Utilities - isFalsy + * @module tutils/utils/isFalsy + */ + +import type { Falsy } from '#src/types' +import includes from './includes' +import isEmptyValue from './is-empty-value' +import isFalse from './is-false' +import isNaN from './is-nan' + +/** + * Checks if `value` is {@linkcode Falsy}. + * + * Falsy values include: + * + * - `''` + * - `0` + * - `0n` + * - `Number.NaN` + * - `false` + * - `null` + * - `undefined` + * + * @todo examples + * + * @param {unknown} value - Value to check + * @return {value is Falsy} `true` if `value` is falsy + */ +const isFalsy = (value: unknown): value is Falsy => { + return ( + isEmptyValue(value) || + isFalse(value) || + isNaN(value) || + includes([0, 0n], value) + ) +} + +export default isFalsy diff --git a/src/utils/is-nan.ts b/src/utils/is-nan.ts new file mode 100644 index 00000000..797a8f6c --- /dev/null +++ b/src/utils/is-nan.ts @@ -0,0 +1,18 @@ +/** + * @file Utilities - isNaN + * @module tutils/utils/isNaN + */ + +import equal from './equal' + +/** + * Checks if `value` is {@linkcode Number.NaN}. + * + * @todo examples + * + * @param {unknown} value - Value to check + * @return {boolean} `true` if `value` is `Number.NaN` + */ +const isNaN = (value: unknown): boolean => equal(Number.NaN, value) + +export default isNaN diff --git a/src/utils/is-true.ts b/src/utils/is-true.ts new file mode 100644 index 00000000..ee542eae --- /dev/null +++ b/src/utils/is-true.ts @@ -0,0 +1,18 @@ +/** + * @file Utilities - isTrue + * @module tutils/utils/isTrue + */ + +import equal from './equal' + +/** + * Checks if `value` is `true`. + * + * @todo examples + * + * @param {unknown} value - Value to check + * @return {value is true} `true` if `value` is `true` + */ +const isTrue = (value: unknown): value is true => equal(true, value) + +export default isTrue