Skip to content

Commit

Permalink
feat(utils): isObjectLike
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
  • Loading branch information
unicornware committed Aug 10, 2023
1 parent 10fa0a9 commit 9bec8ac
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 29 deletions.
34 changes: 23 additions & 11 deletions src/utils/__tests__/is-object-curly.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,41 @@
* @module tutils/utils/tests/unit/isObjectCurly
*/

import INTEGER from '#fixtures/integer'
import TODAY from '#fixtures/today'
import VEHICLE from '#fixtures/vehicle'
import testSubject from '../is-object-curly'

describe('unit:utils/isObjectCurly', () => {
it('should return false if value is not curly-braced object', () => {
it('should return false if value is array', () => {
expect(testSubject([])).to.be.false
})

it('should return false if value is function', () => {
expect(testSubject(vi.fn())).to.be.false
})

it('should return false if value is a primitive', () => {
// Arrange
const cases: Parameters<typeof testSubject>[] = [
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]],
[INTEGER],
[VEHICLE.vin],
[faker.datatype.boolean()],
[faker.number.bigInt()],
[faker.string.hexadecimal({ length: 24 })],
[vi.fn()]
[null],
[undefined]
]

// Act + Expect
cases.forEach(([value]) => expect(testSubject(value)).to.be.false)
})

it('should return true if value is curly-braced object', () => {
// Arrange
const cases: Parameters<typeof testSubject>[] = [
[faker.date.anytime()],
[{ email: faker.internet.email() }]
]
it('should return true if value is instance object', () => {
expect(testSubject(TODAY)).to.be.true
})

// Act + Expect
cases.forEach(([value]) => expect(testSubject(value)).to.be.true)
it('should return true if value is plain object', () => {
expect(testSubject(VEHICLE)).to.be.true
})
})
17 changes: 17 additions & 0 deletions src/utils/__tests__/is-object-like.spec-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @file Type Tests - isObjectLike
* @module tutils/utils/tests/unit-d/isObjectLike
*/

import type { ObjectCurly } from '#src/types'
import type testSubject from '../is-object-like'

describe('unit-d:utils/isObjectLike', () => {
it('should guard ObjectCurly | unknown[]', () => {
// Arrange
type Expect = ObjectCurly | unknown[]

// Expect
expectTypeOf<typeof testSubject>().guards.toEqualTypeOf<Expect>()
})
})
43 changes: 43 additions & 0 deletions src/utils/__tests__/is-object-like.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @file Unit Tests - isObjectLike
* @module tutils/utils/tests/unit/isObjectLike
*/

import INTEGER from '#fixtures/integer'
import TODAY from '#fixtures/today'
import VEHICLE from '#fixtures/vehicle'
import testSubject from '../is-object-like'

describe('unit:utils/isObjectLike', () => {
it('should return false if value is function', () => {
expect(testSubject(vi.fn())).to.be.false
})

it('should return false if value is a primitive', () => {
// Arrange
const cases: Parameters<typeof testSubject>[] = [
[INTEGER],
[VEHICLE.vin],
[faker.datatype.boolean()],
[faker.number.bigInt()],
[faker.string.sample()],
[null],
[undefined]
]

// Act + Expect
cases.forEach(([value]) => expect(testSubject(value)).to.be.false)
})

it('should return true if value is array', () => {
expect(testSubject([])).to.be.true
})

it('should return true if value is instance object', () => {
expect(testSubject(TODAY)).to.be.true
})

it('should return true if value is plain object', () => {
expect(testSubject(VEHICLE)).to.be.true
})
})
10 changes: 4 additions & 6 deletions src/utils/__tests__/is-object.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@
*/

import INTEGER from '#fixtures/integer'
import VEHICLE, { VEHICLE_TAG } from '#fixtures/vehicle'
import type { tag as opaque } from '#src/types/opaque'
import cast from '../cast'
import TODAY from '#fixtures/today'
import VEHICLE from '#fixtures/vehicle'
import testSubject from '../is-object'

describe('unit:utils/isObject', () => {
it('should return false if value is a primitive', () => {
// Arrange
const cases: Parameters<typeof testSubject>[] = [
[INTEGER],
[VEHICLE[cast<typeof opaque>(VEHICLE_TAG)]],
[VEHICLE.vin],
[faker.datatype.boolean()],
[faker.number.bigInt()],
Expand All @@ -36,10 +34,10 @@ describe('unit:utils/isObject', () => {
})

it('should return true if value is instance object', () => {
expect(testSubject(faker.date.anytime())).to.be.true
expect(testSubject(TODAY)).to.be.true
})

it('should return true if value is plain object', () => {
expect(testSubject({ job_title: faker.person.jobTitle() })).to.be.true
expect(testSubject(VEHICLE)).to.be.true
})
})
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export { default as isNumber } from './is-number'
export { default as isNumeric } from './is-numeric'
export { default as isObject } from './is-object'
export { default as isObjectCurly } from './is-object-curly'
export { default as isObjectLike } from './is-object-like'
export { default as isObjectPlain } from './is-object-plain'
export { default as isPrimitive } from './is-primitive'
export { default as isPromise } from './is-promise'
Expand Down
13 changes: 4 additions & 9 deletions src/utils/is-object-curly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,23 @@

import type { ObjectCurly } from '#src/types'
import isArray from './is-array'
import isFunction from './is-function'
import isObject from './is-object'
import isObjectPlain from './is-object-plain'
import isObjectLike from './is-object-like'

/**
* Checks if `value` is a curly-braced object.
*
* A curly-braced object is an object that is not an array or function (e.g.
* instance objects, pojos).
* A curly-braced object is an object-like value that is not an array.
*
* @see {@linkcode ObjectCurly}
* @see {@linkcode isObjectLike}
*
* @todo examples
*
* @param {unknown} value - Value to check
* @return {value is ObjectCurly} `true` if `value` is curly-braced object
*/
const isObjectCurly = (value: unknown): value is ObjectCurly => {
return (
isObjectPlain(value) ||
(!isArray(value) && !isFunction(value) && isObject(value))
)
return !isArray(value) && isObjectLike(value)
}

export default isObjectCurly
24 changes: 24 additions & 0 deletions src/utils/is-object-like.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @file Utilities - isObjectLike
* @module tutils/utils/isObjectLike
*/

import type { ObjectCurly } from '#src/types'
import isNull from './is-null'

/**
* Checks if `value` is object-like.
*
* A value is object-like if it has a `typeof` result of `'object'` and is not
* `null`.
*
* @todo examples
*
* @param {unknown} value - Value to check
* @return {value is ObjectCurly | unknown[]} `true` if `value` is object-like
*/
const isObjectLike = (value: unknown): value is ObjectCurly | unknown[] => {
return !isNull(value) && typeof value === 'object'
}

export default isObjectLike
8 changes: 5 additions & 3 deletions src/utils/is-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

import type { Objectify } from '#src/types'
import isFunction from './is-function'
import isNull from './is-null'
import isObjectLike from './is-object-like'

/**
* Checks if `value` is an object.
* Checks if `value` is a [language type][1] `Object`.
*
* Object types include:
*
Expand All @@ -17,13 +17,15 @@ import isNull from './is-null'
* - instance objects
* - plain objects (pojos)
*
* [1]: http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types
*
* @todo examples
*
* @param {unknown} value - Value to check
* @return {value is Objectify<any>} `true` if `value` is an object
*/
const isObject = (value: unknown): value is Objectify<any> => {
return isFunction(value) || (typeof value === 'object' && !isNull(value))
return isFunction(value) || isObjectLike(value)
}

export default isObject

0 comments on commit 9bec8ac

Please sign in to comment.