From f51ee5085d8168ae3241ba4240c451aa9f147103 Mon Sep 17 00:00:00 2001 From: Piyush Chhabra Date: Wed, 9 Oct 2024 12:17:43 +0530 Subject: [PATCH 1/3] ADD: unit tests for object helpers --- tests/helpers/objectHelper.spec.ts | 240 +++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 tests/helpers/objectHelper.spec.ts diff --git a/tests/helpers/objectHelper.spec.ts b/tests/helpers/objectHelper.spec.ts new file mode 100644 index 0000000..4cc2a92 --- /dev/null +++ b/tests/helpers/objectHelper.spec.ts @@ -0,0 +1,240 @@ +import { InvalidValue } from '../../lib/exceptions'; +import { Obj } from '../../lib/utils'; + +describe('Object Helper', () => { + beforeEach(async () => {}); + + // it('should throw exception', () => { + // const arr = {}; + // expect(Arr.toObj(arr as [], [])).toThrow(InvalidValue); + // }); + + it('should return flattened object with dot notation', () => { + const obj = { + product: { + price: 20, + tags: [{ name: 'good' }], + }, + name: 'piyush', + }; + expect(Obj.dot(obj)).toStrictEqual({ + 'product.price': 20, + name: 'piyush', + 'product.tags': [{ name: 'good' }], + }); + }); + + it('should return flattened object in array format with dot notation', () => { + const obj = { + product: { + price: 20, + tags: [{ name: 'good' }], + }, + name: 'piyush', + }; + expect(Obj.entries(obj)).toStrictEqual([ + ['product.price', 20], + ['product.tags', [{ name: 'good' }]], + ['name', 'piyush'], + ]); + }); + + it('should return object with all string values trimmed', () => { + const obj = { + product: { + price: 20, + name: ' Intent', + tags: [{ name: ' good ' }], + }, + name: ' piyush ', + }; + expect(Obj.trim(obj)).toStrictEqual({ + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }); + }); + + it('should return false for empty and true for notEmpty', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }; + expect(Obj.isEmpty(obj)).toBeFalsy(); + expect(Obj.isNotEmpty(obj)).toBeTruthy(); + }); + + it('should return true for empty and false for notEmpty', () => { + const obj = {}; + expect(Obj.isEmpty(obj)).toBeTruthy(); + expect(Obj.isNotEmpty(obj)).toBeFalsy(); + }); + + it('should return object as a map', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }; + const map = new Map(); + map.set('product', { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }); + map.set('name', 'piyush'); + expect(Obj.asMap(obj)).toStrictEqual(map); + }); + + it('should return true', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }; + expect(Obj.isObj(obj)).toBeTruthy(); + }); + + it('should return false', () => { + const obj = true; + expect(Obj.isObj(obj)).toBeFalsy(); + }); + + it('should throw exception', () => { + const run = () => { + const obj = true; + Obj.isObj(obj, true); + }; + expect(run).toThrow(InvalidValue); + }); + + it('should return value of key', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }; + expect(Obj.get(obj, 'name')).toBe('piyush'); + }); + + it('should return undefined', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }; + expect(Obj.get(obj, 'foo')).toBe(undefined); + }); + + it('should return default value', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }; + expect(Obj.get(obj, 'foo', 'bar')).toBe('bar'); + }); + + it('should return object with sorted keys and sorted values', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ' }], + }, + name: 'piyush', + }; + expect(Obj.sort(obj)).toStrictEqual({ + name: 'piyush', + product: { name: 'Intent', price: 20, tags: [{ name: ' good ' }] }, + }); + }); + + it('should return objects with keys only mentioned to pick', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ', time: 3 }], + }, + name: 'piyush', + }; + const pick = ['product.tags.*.time', 'name']; + expect(Obj.pick(obj, pick)).toStrictEqual({ + name: 'piyush', + product: { tags: [{ time: 3 }] }, + }); + }); + + it('should return objects with all keys but the mentioned ones to leave', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ', time: 3 }], + }, + name: 'piyush', + }; + const leave = ['product.tags.*.time', 'name']; + expect(Obj.except(obj, leave)).toStrictEqual({ + product: { name: 'Intent', price: 20, tags: [{ name: ' good ' }] }, + }); + }); + + it('should return objects with keys only mentioned to pick', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ', time: 3 }], + }, + name: 'piyush', + }; + const pick = ['product.tags.*.times', 'name']; + expect(Obj.pick(obj, pick)).toStrictEqual({ + name: 'piyush', + product: { tags: [{}] }, + }); + }); + + it('should return objects with all keys but the mentioned ones to leave', () => { + const obj = { + product: { + price: 20, + name: 'Intent', + tags: [{ name: ' good ', time: 3 }], + }, + name: 'piyush', + }; + const leave = ['product.tags.*.times', 'name']; + expect(Obj.except(obj, leave)).toStrictEqual({ + product: { + name: 'Intent', + price: 20, + tags: [{ name: ' good ', time: 3 }], + }, + }); + }); +}); From f2bf8f0108e3e226216c4171c207b62da29d893d Mon Sep 17 00:00:00 2001 From: Piyush Chhabra Date: Wed, 9 Oct 2024 12:18:35 +0530 Subject: [PATCH 2/3] ADD: unit tests for numbers helpers --- tests/helpers/numberHelper.spec.ts | 117 +++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 tests/helpers/numberHelper.spec.ts diff --git a/tests/helpers/numberHelper.spec.ts b/tests/helpers/numberHelper.spec.ts new file mode 100644 index 0000000..1108b86 --- /dev/null +++ b/tests/helpers/numberHelper.spec.ts @@ -0,0 +1,117 @@ +import { Num } from '../../lib/utils/number'; + +describe('Numbers Helper', () => { + beforeEach(async () => {}); + + it('should abbrevate with en locale to 1 decimal point precision', () => { + const number = 12345; + const options = { locale: 'en' }; + expect(Num.abbreviate(number, options)).toBe('12.3K'); + }); + + it('should abbrevate with en locale to 3 decimal precision', () => { + const number = 12345; + const options = { precision: 3, locale: 'en' }; + expect(Num.abbreviate(number, options)).toBe('12.345K'); + }); + + it('should abbrevate with en-IN locale to 3 decimal precision', () => { + const number = 12345; + const options = { precision: 3, locale: 'en-IN' }; + expect(Num.abbreviate(number, options)).toBe('12.345T'); + }); + + it('should return number itself', () => { + const number = 12345; + const min = 12300; + const max = 12400; + expect(Num.clamp(number, min, max)).toBe(number); + }); + + it('should return minimum number', () => { + const number = 12345; + const min = 12350; + const max = 12400; + expect(Num.clamp(number, min, max)).toBe(min); + }); + + it('should return maximum number', () => { + const number = 12345; + const min = 12300; + const max = 12340; + expect(Num.clamp(number, min, max)).toBe(max); + }); + + it('should return number in currency style in INR', () => { + const number = 12345; + const options = { currency: 'INR', locale: 'en' }; + expect(Num.currency(number, options)).toBe('₹12,345.00'); + }); + + it('should return number in currency style in USD', () => { + const number = 12345; + const options = { currency: 'USD', locale: 'en' }; + expect(Num.currency(number, options)).toBe('$12,345.00'); + }); + + it('should return number in file size format', () => { + const number = 12345; + expect(Num.fileSize(number)).toBe('12.3KB'); + }); + + it('should return number in file size format with precision 3', () => { + const number = 123456789; + const options = { precision: 3 }; + expect(Num.fileSize(number, options)).toBe('123.457MB'); + }); + + it('should return number in humanize form with precision 1', () => { + const number = 12345; + const options = { precision: 1, locale: 'en' }; + expect(Num.forHumans(number, options)).toBe('12.3 thousand'); + }); + + it('should return number in humanize form with precision 3', () => { + const number = 123456789; + const options = { precision: 3, locale: 'en' }; + expect(Num.forHumans(number, options)).toBe('123.457 million'); + }); + + it('should return number in number system format with precision 1(default)', () => { + const number = 12345.78; + const options = { locale: 'en' }; + expect(Num.format(number, options)).toBe('12,345.8'); + }); + + it('should return number in percents when passed as decimal portion with precision 1(default)', () => { + const number = 17.8; + const options = { locale: 'en' }; + expect(Num.percentage(number, options)).toBe('17.8%'); + }); + + it('should return number in ordinal format', () => { + const number = 231; + expect(Num.ordinal(number)).toBe('231st'); + }); + + it('should return number in ordinal format', () => { + const number = 12345; + expect(Num.ordinal(number)).toBe('12345th'); + }); + + it('should return number in english words', () => { + const number = 12345; + expect(Num.spell(number)).toBe( + 'twelve thousand three hundred and forty five only', + ); + }); + + it('should return false', () => { + const number = '12345'; + expect(Num.isInteger(number)).toBe(false); + }); + it('should return true', () => { + const number = 12345; + expect(Num.isInteger(number)).toBe(true); + }); +}); From 2a809b451cc95f69a6859b3aedf946ccc578a3a9 Mon Sep 17 00:00:00 2001 From: Piyush Chhabra Date: Wed, 9 Oct 2024 12:22:36 +0530 Subject: [PATCH 3/3] ADD: unit tests for array helpers --- lib/utils/array.ts | 17 +++++ tests/helpers/arrayHelper.spec.ts | 100 ++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 tests/helpers/arrayHelper.spec.ts diff --git a/lib/utils/array.ts b/lib/utils/array.ts index 605ada9..c1b37cb 100644 --- a/lib/utils/array.ts +++ b/lib/utils/array.ts @@ -145,4 +145,21 @@ export class Arr { return undefined; } + + static intersect( + arr1: T[], + arr2: M[], + ): Array { + const tempMap = new Map(); + const newArr = [] as Array; + for (const val of arr1) { + tempMap.set(val, 1); + } + + for (const val2 of arr2) { + if (tempMap.has(val2)) newArr.push(val2); + } + + return newArr; + } } diff --git a/tests/helpers/arrayHelper.spec.ts b/tests/helpers/arrayHelper.spec.ts new file mode 100644 index 0000000..44b9078 --- /dev/null +++ b/tests/helpers/arrayHelper.spec.ts @@ -0,0 +1,100 @@ +import { Arr } from '../../lib/utils/array'; + +describe('Array Helper', () => { + beforeEach(async () => {}); + + // it('should throw exception', () => { + // const arr = {}; + // expect(Arr.toObj(arr as [], [])).toThrow(InvalidValue); + // }); + + it('should return object', () => { + const arr = [ + 2, + ['bar', 'piyush', 'intent'], + { + foo: 'bar', + }, + [{ bar: 'foo' }], + ]; + const keys = ['foo', 'chhabra', 'best framework', 'obj']; + expect(Arr.toObj(arr, keys)).toStrictEqual([ + { + foo: 'bar', + chhabra: 'piyush', + 'best framework': 'intent', + }, + { + foo: { bar: 'foo' }, + }, + ]); + }); + + // it('should throw exception', () => { + // const arr = {}; + // expect(Arr.isArray(arr as [], true)).toThrow(InvalidValue); + // }); + + it('should return false', () => { + const arr = {}; + expect(Arr.isArray(arr as [])).toBeFalsy(); + }); + + it('should return false', () => { + const arr = []; + expect(Arr.isArray(arr)).toBeTruthy(); + }); + + it('should return array of nested members flattened', () => { + const arr = [1, [2, 3, 4], [[5, 6], [[7], 8], 9]]; + expect(Arr.collapse(arr)).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); + }); + + it('should return array with random order of input', () => { + const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + const mockMath = Object.create(global.Math); + mockMath.random = () => 0.5; + global.Math = mockMath; + expect(Arr.random(arr)).toStrictEqual([1, 6, 2, 8, 3, 7, 4, 9, 5]); + }); + + it('should return array with sorted order of input', () => { + const arr = [6, 1, 2, 8, 3, 7, 4, 9, 5]; + expect(Arr.sort(arr)).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); + }); + + it('should return array with descending order of input', () => { + const arr = [6, 1, 2, 8, 3, 7, 4, 9, 5]; + expect(Arr.sortDesc(arr)).toStrictEqual([9, 8, 7, 6, 5, 4, 3, 2, 1]); + }); + + it('should return array with common elements from both input arrays', () => { + const arr1 = [1, 2, 3, 4, 5]; + const arr2 = [4, 5, 6, 7, 8]; + expect(Arr.intersect(arr1, arr2)).toStrictEqual([4, 5]); + }); + + it('should return array with elements keys mentioned to pick', () => { + const arr = [ + { developer: { id: 1, name: 'Taylor' } }, + { developer: { id: 2, name: 'Abigail' } }, + ]; + const pick = ['*.developer.name']; + expect(Arr.pick(arr, pick)).toStrictEqual([ + { developer: { name: 'Taylor' } }, + { developer: { name: 'Abigail' } }, + ]); + }); + + it('should return array with all elements except the keys mentioned', () => { + const arr = [ + { developer: { id: 1, name: 'Taylor' } }, + { developer: { id: 2, name: 'Abigail' } }, + ]; + const pick = ['*.developer.name']; + expect(Arr.except(arr, pick)).toStrictEqual([ + { developer: { id: 1 } }, + { developer: { id: 2 } }, + ]); + }); +});