mirror of
https://github.com/dzeiocom/libs.git
synced 2025-04-22 10:52:11 +00:00
feat: Add objectFind
to the object-util lib
Signed-off-by: Florian BOUILLON <f.bouillon@aptatio.com>
This commit is contained in:
parent
2f1e72d77b
commit
a1cd24f399
@ -1,6 +1,6 @@
|
|||||||
/// <reference types="jest" />
|
/// <reference types="jest" />
|
||||||
|
|
||||||
import { isObject, objectClean, objectClone, objectEqual, objectKeys, objectLoop, objectMap, objectOmit, objectRemap, objectSet, objectSize, objectSort, objectValues } from '../src/ObjectUtil'
|
import { isObject, objectClean, objectClone, objectEqual, objectFind, objectKeys, objectLoop, objectMap, objectOmit, objectRemap, objectSet, objectSize, objectSort, objectValues } from '../src/ObjectUtil'
|
||||||
|
|
||||||
describe('Throw if parameter is not an object', () => {
|
describe('Throw if parameter is not an object', () => {
|
||||||
it('should works', () => {
|
it('should works', () => {
|
||||||
@ -102,6 +102,7 @@ describe('Object To Array Tests', () => {
|
|||||||
}
|
}
|
||||||
expect(objectValues(obj)).toEqual(['first', 'second'])
|
expect(objectValues(obj)).toEqual(['first', 'second'])
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('shoud work on arrays', () => {
|
// it('shoud work on arrays', () => {
|
||||||
// const obj = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
// const obj = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
// expect(objectValues(obj)).toEqual(obj)
|
// expect(objectValues(obj)).toEqual(obj)
|
||||||
@ -116,6 +117,7 @@ describe('Object Keys Tests', () => {
|
|||||||
}
|
}
|
||||||
expect(objectKeys(obj)).toEqual(['pouet', 'toto'])
|
expect(objectKeys(obj)).toEqual(['pouet', 'toto'])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shoud work on arrays', () => {
|
it('shoud work on arrays', () => {
|
||||||
const obj = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
const obj = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
expect(objectKeys(obj)).toEqual(obj)
|
expect(objectKeys(obj)).toEqual(obj)
|
||||||
@ -139,6 +141,7 @@ describe('Object Size Tests', () => {
|
|||||||
}
|
}
|
||||||
expect(objectSize(obj)).toBe(11)
|
expect(objectSize(obj)).toBe(11)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shoud return length of an array', () => {
|
it('shoud return length of an array', () => {
|
||||||
const obj = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
const obj = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
expect(objectSize(obj)).toBe(10)
|
expect(objectSize(obj)).toBe(10)
|
||||||
@ -156,10 +159,12 @@ describe('Object sort Tests', () => {
|
|||||||
b: 'first'
|
b: 'first'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('should sort an array (yes stupid)', () => {
|
// it('should sort an array (yes stupid)', () => {
|
||||||
// const arr = [2, 1, 0]
|
// const arr = [2, 1, 0]
|
||||||
// expect(objectSort(arr, (a, b) => a - b)).toEqual([0, 1, 2])
|
// expect(objectSort(arr, (a, b) => a - b)).toEqual([0, 1, 2])
|
||||||
// })
|
// })
|
||||||
|
|
||||||
it('should sort by the specified key', () => {
|
it('should sort by the specified key', () => {
|
||||||
const obj = {
|
const obj = {
|
||||||
b: 'first',
|
b: 'first',
|
||||||
@ -174,6 +179,7 @@ describe('Object sort Tests', () => {
|
|||||||
d: 'fourth'
|
d: 'fourth'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should sort by the specified key', () => {
|
it('should sort by the specified key', () => {
|
||||||
const obj = {
|
const obj = {
|
||||||
b: 'first',
|
b: 'first',
|
||||||
@ -241,7 +247,6 @@ describe('Object Clone Tests', () => {
|
|||||||
expect(clone).not.toEqual(obj)
|
expect(clone).not.toEqual(obj)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
it('should clone with Object.freeze', () => {
|
it('should clone with Object.freeze', () => {
|
||||||
const obj = Object.freeze({
|
const obj = Object.freeze({
|
||||||
pouet: 'first',
|
pouet: 'first',
|
||||||
@ -290,33 +295,42 @@ describe('Object Equal Test', () => {
|
|||||||
it('should be equal', () => {
|
it('should be equal', () => {
|
||||||
expect(objectEqual({pouet: true}, {pouet: true})).toBe(true)
|
expect(objectEqual({pouet: true}, {pouet: true})).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not be equal', () => {
|
it('should not be equal', () => {
|
||||||
expect(objectEqual({pouet: true}, {pouet: false})).toBe(false)
|
expect(objectEqual({pouet: true}, {pouet: false})).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be deeply equal', () => {
|
it('should be deeply equal', () => {
|
||||||
expect(objectEqual({pouet: {is: true}}, {pouet: {is: true}})).toBe(true)
|
expect(objectEqual({pouet: {is: true}}, {pouet: {is: true}})).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not be equal if lengths are differents', () => {
|
it('should not be equal if lengths are differents', () => {
|
||||||
expect(objectEqual({pouet: true, added: true }, {pouet: true})).toBe(false)
|
expect(objectEqual({pouet: true, added: true }, {pouet: true})).toBe(false)
|
||||||
expect(objectEqual({pouet: true }, {pouet: true, added: true})).toBe(false)
|
expect(objectEqual({pouet: true }, {pouet: true, added: true})).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not be equal if lengths are equal but content different', () => {
|
it('should not be equal if lengths are equal but content different', () => {
|
||||||
expect(objectEqual({pouet: true, added: true }, {pouet: true, removed: true})).toBe(false)
|
expect(objectEqual({pouet: true, added: true }, {pouet: true, removed: true})).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be equal object contains null', () => {
|
it('should be equal object contains null', () => {
|
||||||
expect(objectEqual({pouet: null, added: true }, {pouet: true, added: true})).toBe(false)
|
expect(objectEqual({pouet: null, added: true }, {pouet: true, added: true})).toBe(false)
|
||||||
expect(objectEqual({pouet: null, added: true }, {pouet: null, added: true})).toBe(true)
|
expect(objectEqual({pouet: null, added: true }, {pouet: null, added: true})).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be equal object contains undefined', () => {
|
it('should be equal object contains undefined', () => {
|
||||||
expect(objectEqual({pouet: undefined, added: true }, {pouet: true, added: true})).toBe(false)
|
expect(objectEqual({pouet: undefined, added: true }, {pouet: true, added: true})).toBe(false)
|
||||||
expect(objectEqual({pouet: undefined, added: true }, {pouet: undefined, added: true})).toBe(true)
|
expect(objectEqual({pouet: undefined, added: true }, {pouet: undefined, added: true})).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not be deeply equal', () => {
|
it('should not be deeply equal', () => {
|
||||||
expect(objectEqual({pouet: {is: true}}, {pouet: {is: false}})).toBe(false)
|
expect(objectEqual({pouet: {is: true}}, {pouet: {is: false}})).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not be differently equal', () => {
|
it('should not be differently equal', () => {
|
||||||
expect(objectEqual({pouet: true}, {})).toBe(false)
|
expect(objectEqual({pouet: true}, {})).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle every types', () => {
|
it('should handle every types', () => {
|
||||||
expect(objectEqual({
|
expect(objectEqual({
|
||||||
a: [10, {b: 'c'}], d: '1', e: 2, f: true, g: null, h: undefined
|
a: [10, {b: 'c'}], d: '1', e: 2, f: true, g: null, h: undefined
|
||||||
@ -324,6 +338,7 @@ describe('Object Equal Test', () => {
|
|||||||
a: [10, {b: 'c'}], d: '1', e: 2, f: true, g: null, h: undefined
|
a: [10, {b: 'c'}], d: '1', e: 2, f: true, g: null, h: undefined
|
||||||
})).toBe(true)
|
})).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle arrays with empty elements', () => {
|
it('should handle arrays with empty elements', () => {
|
||||||
expect(objectEqual([,true], [,true])).toBe(true)
|
expect(objectEqual([,true], [,true])).toBe(true)
|
||||||
})
|
})
|
||||||
@ -335,11 +350,13 @@ describe('Object Clean Tests', () => {
|
|||||||
objectClean(obj)
|
objectClean(obj)
|
||||||
expect(obj).toEqual({a: '', b: null})
|
expect(obj).toEqual({a: '', b: null})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should clean undefined when told to', () => {
|
it('should clean undefined when told to', () => {
|
||||||
const obj = {a: '', b: null, c: undefined}
|
const obj = {a: '', b: null, c: undefined}
|
||||||
objectClean(obj, {cleanUndefined: true})
|
objectClean(obj, {cleanUndefined: true})
|
||||||
expect(obj).toEqual({a: '', b: null})
|
expect(obj).toEqual({a: '', b: null})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should clean deeply when told to', () => {
|
it('should clean deeply when told to', () => {
|
||||||
const obj = {a: '', b: null, c: {aa: undefined}}
|
const obj = {a: '', b: null, c: {aa: undefined}}
|
||||||
objectClean(obj, {deep: true})
|
objectClean(obj, {deep: true})
|
||||||
@ -351,21 +368,25 @@ describe('Object Clean Tests', () => {
|
|||||||
objectClean(obj, {cleanFalsy: true})
|
objectClean(obj, {cleanFalsy: true})
|
||||||
expect(obj).toEqual({obj: 'util', c: {}})
|
expect(obj).toEqual({obj: 'util', c: {}})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not clean when options.cleanUndefined is false', () => {
|
it('should not clean when options.cleanUndefined is false', () => {
|
||||||
const obj2 = {a: '', b: null, c: undefined}
|
const obj2 = {a: '', b: null, c: undefined}
|
||||||
objectClean(obj2, {cleanUndefined: false})
|
objectClean(obj2, {cleanUndefined: false})
|
||||||
expect(obj2).toEqual({a: '', b: null, c: undefined})
|
expect(obj2).toEqual({a: '', b: null, c: undefined})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should clean null when set', () => {
|
it('should clean null when set', () => {
|
||||||
const obj = {a: '', b: null, c: undefined}
|
const obj = {a: '', b: null, c: undefined}
|
||||||
objectClean(obj, {cleanNull: true})
|
objectClean(obj, {cleanNull: true})
|
||||||
expect(obj).toEqual({a: ''})
|
expect(obj).toEqual({a: ''})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should clean deep by default', () => {
|
it('should clean deep by default', () => {
|
||||||
const obj = {a: '', b: null, c: undefined, d: {da: '', db: null, dc: undefined}}
|
const obj = {a: '', b: null, c: undefined, d: {da: '', db: null, dc: undefined}}
|
||||||
objectClean(obj)
|
objectClean(obj)
|
||||||
expect(obj).toEqual({a: '', b: null, d: {da: '', db: null}})
|
expect(obj).toEqual({a: '', b: null, d: {da: '', db: null}})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should clean deep when set', () => {
|
it('should clean deep when set', () => {
|
||||||
const obj = {a: '', b: null, c: undefined, d: {da: '', db: null, dc: undefined}}
|
const obj = {a: '', b: null, c: undefined, d: {da: '', db: null, dc: undefined}}
|
||||||
objectClean(obj, {deep: true})
|
objectClean(obj, {deep: true})
|
||||||
@ -378,14 +399,17 @@ describe('Object Omit Tests', () => {
|
|||||||
const obj = {a: 'a', b: 'c', c: 'b'}
|
const obj = {a: 'a', b: 'c', c: 'b'}
|
||||||
expect(objectOmit(obj, 'b')).toEqual({a: 'a', c: 'b'})
|
expect(objectOmit(obj, 'b')).toEqual({a: 'a', c: 'b'})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not care when key to omit is not present', () => {
|
it('should not care when key to omit is not present', () => {
|
||||||
const obj = {a: 'a', b: 'c', c: 'b'}
|
const obj = {a: 'a', b: 'c', c: 'b'}
|
||||||
expect(objectOmit(obj, 'b', 'd')).toEqual({a: 'a', c: 'b'})
|
expect(objectOmit(obj, 'b', 'd')).toEqual({a: 'a', c: 'b'})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should work with Object.freeze', () => {
|
it('should work with Object.freeze', () => {
|
||||||
const obj = {a: 'a', b: 'c', c: 'b'}
|
const obj = {a: 'a', b: 'c', c: 'b'}
|
||||||
expect(objectOmit(Object.freeze(obj), 'b', 'd')).toEqual({a: 'a', c: 'b'})
|
expect(objectOmit(Object.freeze(obj), 'b', 'd')).toEqual({a: 'a', c: 'b'})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should work with an array', () => {
|
it('should work with an array', () => {
|
||||||
const obj = [1, 2, 3, 4]
|
const obj = [1, 2, 3, 4]
|
||||||
expect(objectOmit(obj, 1, 3)).toEqual([1,undefined,3,undefined])
|
expect(objectOmit(obj, 1, 3)).toEqual([1,undefined,3,undefined])
|
||||||
@ -396,42 +420,50 @@ describe('Is Object Tests', () => {
|
|||||||
it('null is not an "object"', () => {
|
it('null is not an "object"', () => {
|
||||||
expect(isObject(null)).toBe(false)
|
expect(isObject(null)).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('boolean is not an "object"', () => {
|
it('boolean is not an "object"', () => {
|
||||||
expect(isObject(true)).toBe(false)
|
expect(isObject(true)).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('undefined is not an "object"', () => {
|
it('undefined is not an "object"', () => {
|
||||||
expect(isObject(undefined)).toBe(false)
|
expect(isObject(undefined)).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('string is not an "object"', () => {
|
it('string is not an "object"', () => {
|
||||||
expect(isObject("null")).toBe(false)
|
expect(isObject("null")).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('number is not an "object"', () => {
|
it('number is not an "object"', () => {
|
||||||
expect(isObject(0)).toBe(false)
|
expect(isObject(0)).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('object is an "object"', () => {
|
it('object is an "object"', () => {
|
||||||
expect(isObject({})).toBe(true)
|
expect(isObject({})).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('array is an object', () => expect(isObject([])).toBe(true))
|
it('array is an object', () => expect(isObject([])).toBe(true))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
describe('object remap tests', () => {
|
describe('object remap tests', () => {
|
||||||
it('should works on objects', () => {
|
it('should works on objects', () => {
|
||||||
expect(objectRemap({a: "pouet"}, (value, key) => {
|
expect(objectRemap({a: "pouet"}, (value, key) => {
|
||||||
return {key: key + 'a', value}
|
return {key: key + 'a', value}
|
||||||
})).toEqual({aa: "pouet"})
|
})).toEqual({aa: "pouet"})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should works on arrays', () => {
|
it('should works on arrays', () => {
|
||||||
const pouet: [string] = ['pokemon']
|
const pouet: [string] = ['pokemon']
|
||||||
expect(objectRemap(pouet, (value, key: number) => {
|
expect(objectRemap(pouet, (value, key: number) => {
|
||||||
return {key: key + 2, value}
|
return {key: key + 2, value}
|
||||||
})).toEqual({2: "pokemon"})
|
})).toEqual({2: "pokemon"})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should replace value', () => {
|
it('should replace value', () => {
|
||||||
expect(objectRemap({a: 'a', b: 'b'}, (value) => {
|
expect(objectRemap({a: 'a', b: 'b'}, (value) => {
|
||||||
return {key: 'b', value}
|
return {key: 'b', value}
|
||||||
})).toEqual({b: 'b'})
|
})).toEqual({b: 'b'})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw an error in strict mode', () => {
|
it('should throw an error in strict mode', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
objectRemap({a: 'a', b: 'b'}, (value) => {
|
objectRemap({a: 'a', b: 'b'}, (value) => {
|
||||||
@ -440,3 +472,17 @@ describe('object remap tests', () => {
|
|||||||
}).toThrow()
|
}).toThrow()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('object find', () => {
|
||||||
|
it('should find the first object', () => {
|
||||||
|
expect(objectFind({a: "pou", b: "poue", c: "pouet", d: "pouet"}, (value) => {
|
||||||
|
return value === 'pouet'
|
||||||
|
})).toEqual({key: 'c', value: 'pouet', index: 2})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return undefined if no object is found', () => {
|
||||||
|
expect(objectFind({a: 'no more pouet'}, (value) => {
|
||||||
|
return value === 'pouet'
|
||||||
|
})).toEqual(undefined)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@ -302,6 +302,31 @@ export function objectOmit<T extends BasicObject>(obj: T, ...keys: Array<string
|
|||||||
return cloned
|
return cloned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find an element in an object
|
||||||
|
*
|
||||||
|
* @param obj the object to find within
|
||||||
|
* @param fn the function that find the object
|
||||||
|
* @returns the key, value, index of the element found or undefined
|
||||||
|
*/
|
||||||
|
export function objectFind<T = any, K extends BasicObjectKeys = BasicObjectKeys>(
|
||||||
|
obj: BasicObject<K, T>,
|
||||||
|
fn: (value: T, key: K, index: number) => boolean
|
||||||
|
): {key: K, value: T} | undefined {
|
||||||
|
mustBeObject(obj)
|
||||||
|
let res: {key: K, value: T, index: number} | undefined = undefined
|
||||||
|
objectLoop(obj, (value, key, index) => {
|
||||||
|
const tmp = fn(value, key, index)
|
||||||
|
if (tmp) {
|
||||||
|
res = {
|
||||||
|
key, value, index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !tmp
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return if an item is an object
|
* return if an item is an object
|
||||||
*
|
*
|
||||||
@ -342,6 +367,7 @@ export default {
|
|||||||
objectEqual,
|
objectEqual,
|
||||||
objectClean,
|
objectClean,
|
||||||
objectOmit,
|
objectOmit,
|
||||||
|
objectFind,
|
||||||
isObject,
|
isObject,
|
||||||
mustBeObject
|
mustBeObject
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user