Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yea exactly that #5

Draft
wants to merge 1 commit into
base: main_index
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions __tests__/experiments/isBlank/isBlank.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// ! Example Tester Idea from https://www.30secondsofcode.org/js/s/blank-value/
// * Should Basically Do The Same Thing As is_empty underlaying function from src/is_empty.js
// ? Nested things may give false positives compared to "is_empty" and especially
// ? when compared to "is_empty_nested" function.

const isFalsy = (value) => !value

const isWhitespaceString = (value) => typeof value === 'string' && /^\s*$/.test(value)

const isEmptyCollection = (value) => (Array.isArray(value) || value === Object(value)) && !Object.keys(value).length

const isInvalidDate = (value) => value instanceof Date && Number.isNaN(value.getTime())

const isEmptySet = (value) => value instanceof Set && value.size === 0

const isEmptyMap = (value) => value instanceof Map && value.size === 0

const isBlank = (value) => {
if (isFalsy(value)) return true
if (isWhitespaceString(value)) return true
if (isEmptyCollection(value)) return true
if (isInvalidDate(value)) return true
if (isEmptySet(value)) return true
if (isEmptyMap(value)) return true
return false
}

module.exports = isBlank
78 changes: 78 additions & 0 deletions __tests__/experiments/isBlank/samples/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// ! Example Tester Idea from https://www.30secondsofcode.org/js/s/blank-value/
// * Should Basically Do The Same Thing As is_empty underlaying function from src/is_empty.js
// ? Nested things may give false positives compared to "is_empty" and especially
// ? when compared to "is_empty_nested" function.

const isFalsy = (value) => !value
const isWhitespaceString = (value) => typeof value === 'string' && /^\s*$/.test(value)
const isEmptyCollection = (value) => (Array.isArray(value) || value === Object(value)) && !Object.keys(value).length
const isInvalidDate = (value) => value instanceof Date && Number.isNaN(value.getTime())
const isEmptySet = (value) => value instanceof Set && value.size === 0
const isEmptyMap = (value) => value instanceof Map && value.size === 0

const isBlank = (value) => {
if (isEmptySet(value)) return true
if (isEmptyMap(value)) return true
if (isInvalidDate(value)) return true
if (isWhitespaceString(value)) return true
if (isEmptyCollection(value)) return true
if (isFalsy(value)) return true
return false
}

console.log(isBlank(null)) // true
console.log(isBlank(undefined)) // true
console.log(isBlank(0)) // true
console.log(isBlank(false)) // true
console.log(isBlank('')) // true
console.log(isBlank(' \r\n ')) // true
console.log(isBlank(NaN)) // true

const cLog = console.log

//
// #01.001 : Empty array
const arrayEmpty = []
cLog(`arrayEmpty | ${isBlank(arrayEmpty)} === true | [SLV]: ${arrayEmpty.length}`) // true 0
// #01.002 : (technically) Not empty array
const arraySomething = [[]]
cLog(`arraySomething | ${isBlank(arraySomething)} === false | [SLV]: ${arraySomething.length}`) // false 1

//
// #02.001 : Object that is empty
const objEmpty = {}
cLog(`objEmpty | ${isBlank(objEmpty)} === true | [SLV]: ${objEmpty}`) // true
// #02.002 : Object that is not empty
const objNotEmpty = { v: 11, t: 'ok' }
cLog(`objNotEmpty | ${isBlank(objNotEmpty)} === false | [SLV]: ${objNotEmpty}`) // false

//
// #03.001 : Date() that is invalid
const dateInvalide = new Date('hello')
cLog(`dateInvalide | ${isBlank(dateInvalide)} === true | [SLV]: ${dateInvalide}`) // true
// #03.002 : Date() that is valid
const dateValid = new Date()
cLog(`dateValid | ${isBlank(dateValid)} === false | [SLV]: ${dateValid}`) // false

//
// #04.001 : Set() that is empty
const demoSetEmpty = new Set()
cLog(`demoSetEmpty | ${isBlank(demoSetEmpty)} === true | [SLV]: ${demoSetEmpty.size}`) // true
// #04.002 : Set() that with a value
const demoSet = new Set([1, 2, 3])
cLog(`demoSet | ${isBlank(demoSet)} === false | [SLV]: ${demoSet.size}`) // false 3

//
// #05.001 : Map() that is empty
const demoMapEmpty = new Map()
cLog(`demoMapEmpty | ${isBlank(demoMapEmpty)} === true | [SLV]: ${demoMapEmpty.size}`) // true
// #05.002 : Map() that with a value
const demoMap = new Map()
demoMap.set('a', 0)
cLog(`demoMap | ${isBlank(demoMap)} === false | [SLV]: ${demoMap.size}`) // false 1
// #05.003 : Map() constructor can take an array of key-value pairs
const demoMap2 = new Map([
['a', 0],
['b', 1]
])
cLog(`demoMap2 | ${isBlank(demoMap2)} === false | [SLV]: ${demoMap2.size}`) // false 2
83 changes: 83 additions & 0 deletions __tests__/experiments/isBlank/tryouts/001.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
const isBlank = require('../isBlank')
const { isEmpty } = require('../../../..')

console.assert(typeof isBlank === 'function', 'isBlank should be a function')

const demoMap = new Map([['a', 0]])
const demoEmptyMap = new Map()

const demoSet = new Set([1, 2, 3, 4, 5])
const demoEmptySet = new Set()

const dateInvalid = new Date('hello')
const dateValid = new Date()

const arrayEmpty = []
const arraySomething = [0]

const objEmpty = {}
const objNotEmpty = { v: 11, t: 'ok' }

const testCases = [
[null, true, 'null >> true', true],
[undefined, true, 'undefined >> true', true],
[NaN, true, 'NaN >> true', false],

[0, true, '0 >> true', false],
[1, false, '1 >> false', false],

[false, true, 'false >> true', false],
[true, false, 'true >> false', false],

['', true, '"" >> true', true],
[' \r\n ', true, '" \r\n " >> true', true],
['hello', false, '"hello" >> false', false],

[arrayEmpty, true, '[] >> true', true],
[arraySomething, false, '[0] >> false', false],

[objEmpty, true, '{} >> true', true],
[objNotEmpty, false, '{ a: 0 } >> false', false],

// TODO: 🔁 RETHINK this test case
// NOTE: Rethink the problem since this falls into "v_rifier" category of problems.
[dateInvalid, true, 'new Date("hello") >> true', false], // true],
[dateValid, false, 'new Date() >> false', false],

[demoEmptySet, true, 'new Set() >> true', true],
// TODO: 🚩 Fix this test case for "isEmpty()"
// NOTE: Set with a value is not empty
[demoSet, false, 'new Set([1, 2, 3, 4, 5]) >> false', false],

[demoEmptyMap, true, 'new Map() >> true', true],
// TODO: 🚩 Fix this test case for "isEmpty()"
// NOTE: Map with a value is not empty
[demoMap, false, 'new Map([["a", 0]]) >> false', false]
]

const printInput = (input) =>
!!input && input instanceof Date && input['toISOString'] !== undefined && !Number.isNaN(input.getTime())
? input.toISOString()
: JSON.stringify(input)

console.log(`\n[ isBlank ]>------------------------------------`)

let i = 0
testCases.forEach(([input, expected, info]) => {
console.assert(isBlank(input) === expected, `#${i} | ${info} : isBlank(${printInput(input)}) should be ${expected}`)
i++
})
console.log(`-------------------------------------\n`)

console.log(`[ isEmpty ]>------------------------------------`)

i = 0
testCases.forEach(([input, expected, info, expectedIsEmpty]) => {
console.assert(
isEmpty(input) === expectedIsEmpty,
`#${i} | ${info} : isEmpty(${printInput(input)}) should be ${expectedIsEmpty}`
)
i++
})

console.log(`-------------------------------------\n`)
8 changes: 7 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
export const knownInstances = ['Date', 'Promise', 'Error', 'Boolean', 'Number']

/**
* Checks if a value is an instance of a specific type.
*
* @param {*} val - The value to check.
* @returns {boolean} - Returns true if the value is an instance of a specific type, otherwise returns false.
*/
export const isInstance = (val) => ['Date', 'Promise', 'Error', 'Boolean', 'Number'].indexOf(val) !== -1
export const isKnownInstance = (val) => knownInstances.indexOf(val) !== -1

export const noKeys = (obj) => Object.keys(obj).length === 0

export const notNullObject = (value) => typeof value === 'object' && value !== null

6 changes: 3 additions & 3 deletions src/dev/is_empty-v2.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isInstance } from './constants'
import { isKnownInstance, noKeys, notNullObject } from '../constants'

/**
* Checks if a value is empty.
Expand All @@ -7,8 +7,8 @@ import { isInstance } from './constants'
* @returns {boolean} - Returns true if the value is empty, otherwise false.
*/
const is_empty = (value) => {
if (isInstance(value?.constructor?.name)) return false
return typeof value === 'object' && value !== null ? Object.keys(value).length === 0 : !value
if (isKnownInstance(value?.constructor?.name)) return false
return notNullObject(value) ? noKeys(value) : !value
}

export default is_empty
Expand Down
6 changes: 3 additions & 3 deletions src/dev/is_empty.nested-v2.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { isInstance } from './constants'
import { isKnownInstance, notNullObject } from './constants'

/**
* Checks if a nested value is empty.
* @param {*} value - The value to check.
* @returns {boolean} - Returns true if the value is empty, otherwise false.
*/
const is_empty_nested = (value) => {
if (isInstance(value?.constructor?.name)) return false
if (isKnownInstance(value?.constructor?.name)) return false

if (Array.isArray(value)) return value.length > 0 ? value.every((item) => is_empty_nested(item)) : true

if (typeof value === 'object' && value !== null) {
if (notNullObject(value)) {
const keys = Object.keys(value)
return keys.length > 0
? keys.every((key) => Object.prototype.hasOwnProperty.call(value, key) && is_empty_nested(value[key]))
Expand Down
20 changes: 9 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ import is_empty_nested from './is_empty.nested'
* @param {*} v - The value to check.
* @returns {boolean} - Returns `true` if the value is empty, `false` otherwise.
*/
export const isEmpty = (v) => is_empty(v)
export const isEmpty = is_empty

/**
* Checks if a nested value is empty.
* @function isEmptyNested
* @param {*} v - The nested value to check.
* @returns {boolean} - Returns `true` if the nested value is empty, `false` otherwise.
*/
export const isEmptyNested = is_empty_nested

/**
* Checks if a value is not empty.
Expand All @@ -21,14 +29,6 @@ export const isEmpty = (v) => is_empty(v)
*/
export const isNotEmpty = (v) => !is_empty(v)

/**
* Checks if a nested value is empty.
* @function isEmptyNested
* @param {*} v - The nested value to check.
* @returns {boolean} - Returns `true` if the nested value is empty, `false` otherwise.
*/
export const isEmptyNested = (v) => is_empty_nested(v)

/**
* Checks if a nested value is not empty.
* @function isNotEmptyNested
Expand All @@ -37,5 +37,3 @@ export const isEmptyNested = (v) => is_empty_nested(v)
*/
export const isNotEmptyNested = (v) => !is_empty_nested(v)

export { is_empty, is_empty_nested }

12 changes: 4 additions & 8 deletions src/is_empty.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { isInstance } from './constants'
import { isKnownInstance, noKeys, notNullObject } from './constants'

/**
* Checks if a value is empty.
*
* @param {*} value - The value to check.
* @returns {boolean} - Returns true if the value is empty, otherwise false.
*/
const is_empty = (value) => {
export default function is_empty(value) {
if (value === undefined) return true

if (isInstance(value?.constructor?.name)) return false
if (isKnownInstance(value?.constructor?.name)) return false

if (typeof value === 'object' && value !== null) return Object.keys(value).length === 0

return !value
return notNullObject(value) ? noKeys(value) : !value
}

export default is_empty

10 changes: 4 additions & 6 deletions src/is_empty.nested.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { isInstance } from './constants'
import { isKnownInstance, notNullObject } from './constants'

/**
* Checks if a nested value is empty.
* @param {*} value - The value to check.
* @returns {boolean} - Returns true if the value is empty, otherwise false.
*/
const is_empty_nested = (value) => {
export default function is_empty_nested(value) {
if (value === undefined) return true

if (isInstance(value?.constructor?.name)) return false
if (isKnownInstance(value?.constructor?.name)) return false

if (Array.isArray(value)) {
if (value.length === 0) return true
Expand All @@ -20,7 +20,7 @@ const is_empty_nested = (value) => {
return true
}

if (typeof value === 'object' && value !== null) {
if (notNullObject(value)) {
const keys = Object.keys(value)
if (keys.length === 0) return true
let i = 0
Expand All @@ -35,5 +35,3 @@ const is_empty_nested = (value) => {
return !value
}

export default is_empty_nested