Skip to content

Commit

Permalink
✨ Add isJSONObject function
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed May 15, 2021
1 parent 147a199 commit 1090447
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 0 deletions.
1 change: 1 addition & 0 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export { isBigint } from './src/isBigint.ts'
export { isBoolean } from './src/isBoolean.ts'
export { isEmpty } from './src/isEmpty.ts'
export { isFunction } from './src/isFunction.ts'
export { isJSONObject } from './src/isJSONObject.ts'
export { isNaN } from './src/isNaN.ts'
export { isNil } from './src/isNil.ts'
export { isNill } from './src/isNill.ts'
Expand Down
28 changes: 28 additions & 0 deletions src/_/constructorName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { and } from '../and.ts'
import { ifElse } from '../ifElse.ts'
import { isNil } from '../isNil.ts'
import { N } from '../N.ts'

/**
* Safe getter for `constructor.name`.
* @param val - Any value
* @returns If `val` is `null` or `undefined`, empty string; otherwise `constructor.name`
*
* @example
* ```ts
* constructorName(null) // ''
* constructorName(undefined) // ''
* constructorName({}) // 'Object'
* constructorName('') // 'String'
* ```
*
* @internal
*/
const constructorName = (val: unknown): string =>
ifElse(
and(N(isNil(val)), () => (val as Record<string, unknown>).constructor),
() => (val as Record<string, unknown>).constructor.name ?? '',
''
)

export { constructorName }
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
export { _ } from 'https://x.nest.land/arithmetic4@0.1.1/mod.ts'
export const NULL = null
export const JSON_OBJECT = 'Object'

const { prototype, entries, keys, values } = Object
const { hasOwnProperty } = prototype
Expand Down
27 changes: 27 additions & 0 deletions src/isJSONObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.

import { constructorName } from './_/constructorName.ts'
import { JSON_OBJECT } from './constants/index.ts'

/**
* Whatever argument is JSON Object or not.
*
* @param val - Input any value
* @returns if `val` is JSON Object `true` otherwise; `false`
*
* @example
* ```ts
* isJSONObject({ hoge: 'huga'}) // true
* isJSONObject(Object()) // true
* isJSONObject(new Object()) // true
*
* isJSONObject([]) // false
* isJSONObject(new Set()) // false
* ```
*
* @beta
*/
const isJSONObject = (val: unknown): val is Record<PropertyKey, unknown> =>
constructorName(val) === JSON_OBJECT

export { isJSONObject }
68 changes: 68 additions & 0 deletions test/_/constructorName.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
import { assertEquals } from '../../dev_deps.ts'
import { constructorName } from '../../src/_/constructorName.ts'
import { isSymbol } from '../../src/isSymbol.ts'

Deno.test('constructorName', () => {
function fn() {
true
}
class Class {}
const table: [unknown, string][] = [
[Object, 'Function'],
[new Object(), 'Object'],
[Object(), 'Object'],
[{}, 'Object'],
[{ hoge: 'huga' }, 'Object'],
[new Number(), 'Number'],
[Number(), 'Number'],
[Number, 'Function'],
[1, 'Number'],
['', 'String'],
[String(), 'String'],
[String, 'Function'],
[new String(), 'String'],
[new Boolean(), 'Boolean'],
[true, 'Boolean'],
[Boolean, 'Function'],
[new Boolean(), 'Boolean'],
[Boolean(), 'Boolean'],
[undefined, ''],
[null, ''],
[Symbol(), 'Symbol'],
[Symbol, 'Function'],
[1n, 'BigInt'],
[BigInt, 'Function'],
[Array, 'Function'],
[Array([]), 'Array'],
[new Array([]), 'Array'],
[[], 'Array'],
[Date, 'Function'],
[new Date(0), 'Date'],
[Date(), 'String'],
[/a/, 'RegExp'],
[RegExp, 'Function'],
[new RegExp(''), 'RegExp'],
[Error, 'Function'],
[Error(''), 'Error'],
[new Error(), 'Error'],
[TypeError, 'Function'],
[TypeError(), 'TypeError'],
[new TypeError(), 'TypeError'],
[Set, 'Function'],
[new Set(), 'Set'],
[Map, 'Function'],
[new Map(), 'Map'],
[() => true, 'Function'],
[fn, 'Function'],
[Class, 'Function'],
[new Class(), 'Class']
]
table.forEach(([val, expected]) => {
assertEquals(
constructorName(val),
expected,
`constructorName(${isSymbol(val) ? 'symbol' : val}) -> ${expected}`
)
})
})
61 changes: 61 additions & 0 deletions test/isJSONObject.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license.
import { assertEquals } from '../dev_deps.ts'
import { isJSONObject } from '../src/isJSONObject.ts'
import { isSymbol } from '../src/isSymbol.ts'
import {
BIG1,
DATE,
EMPTY_ARRAY,
EMPTY_OBJECT,
EMPTY_STRING,
MAP,
ONE,
SET,
SYMBOL,
VOID_FN,
VOID_PROMISE,
WEAK_MAP,
WEAK_SET,
ZERO
} from './index.ts'

Deno.test('isJSONObject', () => {
const table: [unknown, boolean][] = [
[EMPTY_OBJECT, true],
[Object(), true],
[{ nest: {} }, true],
[new Object(), true],
[new Object({ hoge: 'huga' }), true],
[new Object({ hoge: [], huga: {} }), true],
[Object, false],
[NaN, false],
[Infinity, false],
[-Infinity, false],
[null, false],
[undefined, false],
[ZERO, false],
[ONE, false],
[EMPTY_STRING, false],
['test', false],
[false, false],
[true, false],
[BIG1, false],
[SYMBOL, false],
[EMPTY_ARRAY, false],
[[[]], false],
[MAP, false],
[SET, false],
[WEAK_MAP, false],
[WEAK_SET, false],
[VOID_FN, false],
[VOID_PROMISE, false],
[DATE, false]
]
table.forEach(([val, expected]) => {
assertEquals(
isJSONObject(val),
expected,
`isJSONObject(${isSymbol(val) ? 'symbol' : val}) -> ${expected}`
)
})
})

0 comments on commit 1090447

Please sign in to comment.