From 3c7eb23330ca20fb9aaec11404a411bd13f7f8da Mon Sep 17 00:00:00 2001 From: Vinayak Sarawagi Date: Mon, 7 Oct 2024 22:10:58 +0530 Subject: [PATCH 1/8] added test suite for number helper methods wip array, string and object helpers --- lib/config/__mocks__/service.ts | 3 + lib/config/service.ts | 0 lib/utils/tests/array.spec.ts | 12 ++++ lib/utils/tests/number.spec.ts | 75 ++++++++++++++++++++ lib/utils/tests/object.spec.ts | 12 ++++ lib/utils/tests/string.spec.ts | 121 ++++++++++++++++++++++++++++++++ 6 files changed, 223 insertions(+) create mode 100644 lib/config/__mocks__/service.ts create mode 100644 lib/config/service.ts create mode 100644 lib/utils/tests/array.spec.ts create mode 100644 lib/utils/tests/number.spec.ts create mode 100644 lib/utils/tests/object.spec.ts create mode 100644 lib/utils/tests/string.spec.ts diff --git a/lib/config/__mocks__/service.ts b/lib/config/__mocks__/service.ts new file mode 100644 index 0000000..a4d1f8f --- /dev/null +++ b/lib/config/__mocks__/service.ts @@ -0,0 +1,3 @@ +export const IntentConfig = { + get: jest.fn(), +}; diff --git a/lib/config/service.ts b/lib/config/service.ts new file mode 100644 index 0000000..e69de29 diff --git a/lib/utils/tests/array.spec.ts b/lib/utils/tests/array.spec.ts new file mode 100644 index 0000000..36ff5b6 --- /dev/null +++ b/lib/utils/tests/array.spec.ts @@ -0,0 +1,12 @@ +import { Arr } from '../array'; + +jest.mock('../../config/service'); + +describe('Array Helpers', () => { + beforeEach(async () => {}); + + it('should collapse a nested array in a single level array', () => { + const sample1 = ['a', ['b', ['c'], 1], 2]; + expect(Arr.collapse(sample1)).toStrictEqual(['a', 'b', 'c', 1, 2]); + }); +}); diff --git a/lib/utils/tests/number.spec.ts b/lib/utils/tests/number.spec.ts new file mode 100644 index 0000000..c77a764 --- /dev/null +++ b/lib/utils/tests/number.spec.ts @@ -0,0 +1,75 @@ +import { Num } from '../number'; + +jest.mock('../../config/service'); + +describe('Number Helpers', () => { + beforeEach(async () => {}); + + it('abbreviates the passed number to abbreviated format', () => { + const num = 1000; + expect(Num.abbreviate(num)).toStrictEqual('1K'); + }); + + it('abbreviates the passed number to a abbreviated format, but with precision', () => { + const num = 1200; + expect(Num.abbreviate(num, { precision: 2 })).toStrictEqual('1.2K'); + }); + + it('abbreviates the passed number to a abbreviated format, but with different locale', () => { + const num = 1200; + expect(Num.abbreviate(num, { locale: 'hi' })).toStrictEqual('1.2 हज़ार'); + }); + + it('should conver the number to indian currency format', () => { + const num = 12300; + expect(Num.currency(num, { currency: 'INR' })).toStrictEqual('₹12,300.00'); + }); + + it('should conver the number to dollar currency format', () => { + const num = 12300; + expect(Num.currency(num, { currency: 'USD' })).toStrictEqual('$12,300.00'); + }); + + it('should convert the number to file size representation', () => { + const samples = { 1000: '1KB', 1024: '1KB', [1024 * 1024 * 1.5]: '1.57MB' }; + expect(Num.fileSize(1000)).toStrictEqual('1KB'); + expect(Num.fileSize(1024)).toStrictEqual('1KB'); + expect(Num.fileSize(1024 * 1024 * 1.5, { precision: 2 })).toStrictEqual( + '1.57MB', + ); + }); + + it('should convert the number to human readable format', () => { + expect(Num.forHumans(100)).toStrictEqual('100'); + expect(Num.forHumans(1200)).toStrictEqual('1.2 thousand'); + }); + + it('should convert the number to human readable format, with precision', () => { + expect(Num.forHumans(1230, { precision: 2 })).toStrictEqual( + '1.23 thousand', + ); + }); + + it('should convert the number to human readable format, with locale', () => { + expect(Num.forHumans(1200, { locale: 'fr' })).toStrictEqual('1,2 millier'); + }); + + it('should format the number to the given locale string', () => { + expect(Num.format(1000)).toStrictEqual('1,000'); + expect(Num.format(1000, { locale: 'fr' })).toStrictEqual('1 000'); + expect(Num.format(1200)).toStrictEqual('1,200'); + }); + + it('converts the given number to the ordinal format', () => { + expect(Num.ordinal(1)).toStrictEqual('1st'); + expect(Num.ordinal(2)).toStrictEqual('2nd'); + expect(Num.ordinal(3)).toStrictEqual('3rd'); + expect(Num.ordinal(20)).toStrictEqual('20th'); + }); + + it('converts the number to a percentage format with support for precision and locale config', () => { + expect(Num.percentage(10)).toStrictEqual('10.0%'); + expect(Num.percentage(10, { locale: 'fr' })).toStrictEqual('10,0 %'); + expect(Num.percentage(10.123, { precision: 2 })).toStrictEqual('10.12%'); + }); +}); diff --git a/lib/utils/tests/object.spec.ts b/lib/utils/tests/object.spec.ts new file mode 100644 index 0000000..6de865f --- /dev/null +++ b/lib/utils/tests/object.spec.ts @@ -0,0 +1,12 @@ +import { Arr } from '../array'; + +jest.mock('../../config/service'); + +describe('Object Helpers', () => { + beforeEach(async () => {}); + + it('should collapse a nested array in a single level array', () => { + const sample1 = ['a', ['b', ['c'], 1], 2]; + expect(Arr.collapse(sample1)).toStrictEqual(['a', 'b', 'c', 1, 2]); + }); +}); diff --git a/lib/utils/tests/string.spec.ts b/lib/utils/tests/string.spec.ts new file mode 100644 index 0000000..a691ce0 --- /dev/null +++ b/lib/utils/tests/string.spec.ts @@ -0,0 +1,121 @@ +import { Str } from '../string'; + +jest.mock('../../config/service'); + +describe('String Helper', () => { + beforeEach(async () => {}); + + it('returns the part of the string present after the passed delimiter', () => { + const string = Str.after('Hello, World!!', ','); + expect(string).toBe(' World!!'); + }); + + it('returns the part of the string befored the passed delimiter', () => { + const string = Str.before('Hello, World!!', ','); + expect(string).toBe('Hello'); + }); + + it('compares the string with pattern', () => { + const string = 'users:create'; + const patterns = { 'users:create': true, '*:create': true, admin: false }; + for (const pattern in patterns) { + expect(Str.is(string, pattern)).toBe(patterns[pattern]); + } + }); + + it('returns the string present between the specified stat and end delimiters', () => { + const sentence = 'The quick brown fox jumps over a lazy dog.'; + const result = Str.between(sentence, 'brown', 'jumps'); + expect(result).toBe(' fox '); + }); + + it('converts the string to a camelCase', () => { + const samples = { + intent_js: 'intentJs', + 'quick brown fox jumps': 'quickBrownFoxJumps', + // "Hey_there, What's up?": 'heyThereWhatSUp', + }; + for (const str in samples) { + expect(Str.camel(str)).toBe(samples[str]); + } + }); + + it('check if string contains the specified string', () => { + const samples = { over: true, over2: false }; + const sentence = 'The quick brown fox jumps over a lazy dog.'; + + for (const sample in samples) { + expect(Str.contains(sentence, sample)).toBe(samples[sample]); + } + }); + + it('check if string contains all specified strings', () => { + const sentence = 'The quick brown fox jumps over a lazy dog.'; + expect(Str.containsAll(sentence, ['fox', 'dog'])).toBe(true); + expect(Str.containsAll(sentence, ['fox', 'whale'])).toBe(false); + }); + + it('returns true if string ends with the specified delimitter', () => { + const sentence = 'The quick brown fox jumps over a lazy dog.'; + expect(Str.endsWith(sentence, 'dog.')).toBe(true); + }); + + it('returns false if string ends with the specified delimitter', () => { + const sentence = 'The quick brown fox jumps over a lazy dog.'; + expect(Str.endsWith(sentence, 'dog2.')).toBe(false); + }); + + it('should return the string to headline', () => { + const sentence = 'Is this real?'; + expect(Str.headline(sentence)).toBe('Is This Real?'); + }); + + it('should pluralize the sentence', () => { + const string = `Vinayak ${Str.pluralize('have')} 5 ${Str.pluralize( + 'apple', + )}.`; + expect(string).toBe('Vinayak has 5 apples.'); + }); + + it('should replace using string', () => { + const string = 'vinayak don'; + const find = 'don'; + const replace = 'sarawagi'; + expect(Str.replace(string, find, replace)).toBe('vinayak sarawagi'); + }); + + it('should replace using regex', () => { + const string = 'vinayak don'; + const find = 'don'; + const replace = 'sarawagi'; + expect(Str.replace(string, find, replace)).toBe('vinayak sarawagi'); + }); + + it('should replace all occurences using string', () => { + const string = 'vinayak don don don don'; + const find = 'don'; + const replace = 'sarawagi'; + expect(Str.replace(string, find, replace)).toBe( + 'vinayak sarawagi sarawagi sarawagi sarawagi', + ); + }); + + it('should replace all occurences using regex', () => { + const string = 'Virat Kohli says Ben Stokes'; + const replacements = { + 'Ben Stokes': 'OUT!!', + }; + expect(Str.swap(string, replacements)).toBe('Virat Kohli says OUT!!'); + }); + + it('should convert to snake case', () => { + const string = 'IntentJs - For the devs_whoHaveTheIntent'; + expect(Str.snake(string)).toBe( + 'intent_js_for_the_devs_who_have_the_intent', + ); + }); + + it('should singularize', () => { + expect(Str.singular('indices')).toBe('index'); + }); +}); From 2d0173ca2ec9dece73b5de3a523afa425b01f59b Mon Sep 17 00:00:00 2001 From: Vinayak Sarawagi Date: Tue, 8 Oct 2024 08:44:49 +0530 Subject: [PATCH 2/8] wip test cases for strings --- lib/utils/tests/string.spec.ts | 99 +++++++++++++++++++++++++++++++ packages/core/lib/utils/string.ts | 2 +- 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/lib/utils/tests/string.spec.ts b/lib/utils/tests/string.spec.ts index a691ce0..fc1d502 100644 --- a/lib/utils/tests/string.spec.ts +++ b/lib/utils/tests/string.spec.ts @@ -70,6 +70,105 @@ describe('String Helper', () => { expect(Str.headline(sentence)).toBe('Is This Real?'); }); + it('should validate if the string is email or not', () => { + const samples = { + 'hi@tryintent.com': true, + 'tryintent.com': false, + }; + for (const email in samples) { + expect(Str.isEmail(email)).toStrictEqual(samples[email]); + } + }); + + it('should validate if the given string is a valid JSON or not', () => { + const samples = { + '{"name": "Intent"}': true, + '{"name": "Intent"': false, + }; + + for (const json in samples) { + expect(Str.isJson(json)).toStrictEqual(samples[json]); + } + }); + + it('should validate if the string is a valid URL or not', () => { + const samples = { + 'https://tryintent.com': true, + 'tryintent.com': true, + 'docs.tryintent.com': true, + 'http2://tryintent.com': false, + }; + + for (const url in samples) { + expect(Str.isUrl(url)).toStrictEqual(samples[url]); + } + }); + + it('should validate if the string is valid ulid or not', () => { + const samples = { + ABCDOKMK: false, + '01ARZ3NDEKTSV4RRFFQ69G5FAV': true, + }; + for (const ulid in samples) { + expect(Str.isUlid(ulid)).toStrictEqual(samples[ulid]); + } + }); + + it('should transform the string to kebab case', () => { + const samples = { + intent_js: 'intent-js', + 'quick brown fox jumps': 'quick-brown-fox-jumps', + "Hey_there, What's up?": 'hey-there-what-s-up', + }; + for (const str in samples) { + expect(Str.kebab(str)).toStrictEqual(samples[str]); + } + }); + + it('should convert the first character of a string to lowercase', () => { + const samples = { + INTENT: 'iNTENT', + Intent: 'intent', + }; + for (const str in samples) { + expect(Str.lcfirst(str)).toStrictEqual(samples[str]); + } + }); + + it('returns the correct length of a string', () => { + expect(Str.len('intent')).toStrictEqual(6); + expect(Str.len(undefined)).toStrictEqual(0); + }); + + it('should returns only `n` length of character for a given string', () => { + const sentence = 'The quick brown fox jumps over a lazy dog.'; + expect(Str.limit(sentence, 15)).toStrictEqual('The quick brown...'); + expect(Str.limit(sentence, 15, '!!!')).toStrictEqual('The quick brown!!!'); + expect(Str.limit(sentence, 500)).toStrictEqual(sentence); + }); + + it('should converts the string to lowercase', () => { + expect(Str.lower('HEY THERE!!')).toStrictEqual('hey there!!'); + }); + + it('should mask the string after certain characters', () => { + expect(Str.mask('hi@tryintent.com', '*', 7)).toStrictEqual( + 'hi@tryi*********', + ); + }); + + it('should pad both ends of the string with character to a defined length', () => { + expect(Str.padBoth('intent', 10, '--')).toStrictEqual('--intent--'); + }); + + it('should only pad left of the string with character to a defined length', () => { + expect(Str.padLeft('intent', 10, '--')).toStrictEqual('----intent'); + }); + + it('should only pad right of the string with character to a defined length', () => { + expect(Str.padRight('intent', 10, '--')).toStrictEqual('intent----'); + }); + it('should pluralize the sentence', () => { const string = `Vinayak ${Str.pluralize('have')} 5 ${Str.pluralize( 'apple', diff --git a/packages/core/lib/utils/string.ts b/packages/core/lib/utils/string.ts index 4144b90..b3fe5ea 100644 --- a/packages/core/lib/utils/string.ts +++ b/packages/core/lib/utils/string.ts @@ -208,7 +208,7 @@ export class Str { return !Str.isString(value); }; - static len = (str: string): number => { + static len = (str?: string): number => { return str?.length ?? 0; }; From c1f63e27c3bbae61df9cfb4ec7b8af1f0a6063af Mon Sep 17 00:00:00 2001 From: Vinayak Sarawagi Date: Tue, 8 Oct 2024 08:59:13 +0530 Subject: [PATCH 3/8] add test cases for string replace helpers --- lib/utils/tests/string.spec.ts | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/lib/utils/tests/string.spec.ts b/lib/utils/tests/string.spec.ts index fc1d502..143e331 100644 --- a/lib/utils/tests/string.spec.ts +++ b/lib/utils/tests/string.spec.ts @@ -169,6 +169,54 @@ describe('String Helper', () => { expect(Str.padRight('intent', 10, '--')).toStrictEqual('intent----'); }); + it('should remove the given substring in a given string', () => { + const sentence = 'The quick brown fox jumps over a lazy dog.'; + expect(Str.remove(sentence, 'quick ')).toStrictEqual( + 'The brown fox jumps over a lazy dog.', + ); + expect(Str.remove(sentence, ' ')).toStrictEqual( + 'Thequickbrownfoxjumpsoveralazydog.', + ); + }); + + it('should repeat the given string defined number of times.', () => { + expect(Str.repeat('chug ', 5)).toStrictEqual('chug chug chug chug chug '); + }); + + it('should replace the given string with another string', () => { + expect(Str.replace('I hate intent!', 'hate', 'love')).toStrictEqual( + 'I love intent!', + ); + expect(Str.replace('I Hate intent!', 'hate', 'love', true)).toStrictEqual( + 'I love intent!', + ); + }); + + it('should replace the matching string sequentially with the string array', () => { + const str = 'I will be there between ? and ?'; + expect(Str.replaceArray(str, '?', ['8:30', '9:30PM'])).toStrictEqual( + 'I will be there between 8:30 and 9:30PM', + ); + }); + + it('should only replace the first matching string with the the replacement string', () => { + const sentence = 'the quick brown fox jumps over the lazy dog.'; + expect(Str.replaceFirst(sentence, 'the', 'a')).toStrictEqual( + 'a quick brown fox jumps over the lazy dog.', + ); + }); + + it('should only replace the last matching string with the the replacement string', () => { + const sentence = 'the quick brown fox jumps over the lazy dog.'; + expect(Str.replaceLast(sentence, 'the', 'a')).toStrictEqual( + 'the quick brown fox jumps over a lazy dog.', + ); + }); + + it('should correctly reverse the given string', () => { + expect(Str.reverse('wtf! why reverse?')).toStrictEqual('?esrever yhw !ftw'); + }); + it('should pluralize the sentence', () => { const string = `Vinayak ${Str.pluralize('have')} 5 ${Str.pluralize( 'apple', From bb9d8ce84aa8b2f5266a115c897302c6ed352873 Mon Sep 17 00:00:00 2001 From: Piyush Chhabra Date: Sat, 12 Oct 2024 23:39:32 +0530 Subject: [PATCH 4/8] Feat/helper unit tests (#28) * ADD: unit tests for object helpers * ADD: unit tests for numbers helpers * ADD: unit tests for array helpers --- packages/core/lib/utils/array.ts | 17 ++ tests/helpers/arrayHelper.spec.ts | 100 ++++++++++++ tests/helpers/numberHelper.spec.ts | 117 ++++++++++++++ tests/helpers/objectHelper.spec.ts | 240 +++++++++++++++++++++++++++++ 4 files changed, 474 insertions(+) create mode 100644 tests/helpers/arrayHelper.spec.ts create mode 100644 tests/helpers/numberHelper.spec.ts create mode 100644 tests/helpers/objectHelper.spec.ts diff --git a/packages/core/lib/utils/array.ts b/packages/core/lib/utils/array.ts index 77c4fac..068af92 100644 --- a/packages/core/lib/utils/array.ts +++ b/packages/core/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 } }, + ]); + }); +}); 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); + }); +}); 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 7629d84d82d866b24bfc316185f87de2a209da05 Mon Sep 17 00:00:00 2001 From: Vinayak Sarawagi Date: Mon, 21 Oct 2024 00:23:34 +0530 Subject: [PATCH 5/8] update helpers --- lib/utils/tests/array.spec.ts | 91 +++++++++- lib/utils/tests/number.spec.ts | 133 +++++++++----- lib/utils/tests/object.spec.ts | 218 +++++++++++++++++++++- packages/core/lib/console/consoleIO.ts | 23 +-- packages/core/lib/utils/helpers.ts | 24 +-- packages/core/lib/utils/object.ts | 26 ++- tests/helpers/arrayHelper.spec.ts | 100 ----------- tests/helpers/numberHelper.spec.ts | 117 ------------ tests/helpers/objectHelper.spec.ts | 240 ------------------------- 9 files changed, 418 insertions(+), 554 deletions(-) delete mode 100644 tests/helpers/arrayHelper.spec.ts delete mode 100644 tests/helpers/numberHelper.spec.ts delete mode 100644 tests/helpers/objectHelper.spec.ts diff --git a/lib/utils/tests/array.spec.ts b/lib/utils/tests/array.spec.ts index 36ff5b6..8ddf9d8 100644 --- a/lib/utils/tests/array.spec.ts +++ b/lib/utils/tests/array.spec.ts @@ -2,11 +2,94 @@ import { Arr } from '../array'; jest.mock('../../config/service'); -describe('Array Helpers', () => { +describe('Array Helper', () => { beforeEach(async () => {}); - it('should collapse a nested array in a single level array', () => { - const sample1 = ['a', ['b', ['c'], 1], 2]; - expect(Arr.collapse(sample1)).toStrictEqual(['a', 'b', 'c', 1, 2]); + // 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 } }, + ]); }); }); diff --git a/lib/utils/tests/number.spec.ts b/lib/utils/tests/number.spec.ts index c77a764..9260c72 100644 --- a/lib/utils/tests/number.spec.ts +++ b/lib/utils/tests/number.spec.ts @@ -2,74 +2,117 @@ import { Num } from '../number'; jest.mock('../../config/service'); -describe('Number Helpers', () => { +describe('Numbers Helper', () => { beforeEach(async () => {}); - it('abbreviates the passed number to abbreviated format', () => { - const num = 1000; - expect(Num.abbreviate(num)).toStrictEqual('1K'); + it('should abbrevate with en locale to 1 decimal point precision', () => { + const number = 12345; + expect(Num.abbreviate(number)).toBe('12.3K'); }); - it('abbreviates the passed number to a abbreviated format, but with precision', () => { - const num = 1200; - expect(Num.abbreviate(num, { precision: 2 })).toStrictEqual('1.2K'); + 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('abbreviates the passed number to a abbreviated format, but with different locale', () => { - const num = 1200; - expect(Num.abbreviate(num, { locale: 'hi' })).toStrictEqual('1.2 हज़ार'); + 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.345K'); }); - it('should conver the number to indian currency format', () => { - const num = 12300; - expect(Num.currency(num, { currency: 'INR' })).toStrictEqual('₹12,300.00'); + it('should return number itself', () => { + const number = 12345; + const min = 12300; + const max = 12400; + expect(Num.clamp(number, min, max)).toBe(number); }); - it('should conver the number to dollar currency format', () => { - const num = 12300; - expect(Num.currency(num, { currency: 'USD' })).toStrictEqual('$12,300.00'); + it('should return minimum number', () => { + const number = 12345; + const min = 12350; + const max = 12400; + expect(Num.clamp(number, min, max)).toBe(min); }); - it('should convert the number to file size representation', () => { - const samples = { 1000: '1KB', 1024: '1KB', [1024 * 1024 * 1.5]: '1.57MB' }; - expect(Num.fileSize(1000)).toStrictEqual('1KB'); - expect(Num.fileSize(1024)).toStrictEqual('1KB'); - expect(Num.fileSize(1024 * 1024 * 1.5, { precision: 2 })).toStrictEqual( - '1.57MB', - ); + it('should return maximum number', () => { + const number = 12345; + const min = 12300; + const max = 12340; + expect(Num.clamp(number, min, max)).toBe(max); }); - it('should convert the number to human readable format', () => { - expect(Num.forHumans(100)).toStrictEqual('100'); - expect(Num.forHumans(1200)).toStrictEqual('1.2 thousand'); + 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 convert the number to human readable format, with precision', () => { - expect(Num.forHumans(1230, { precision: 2 })).toStrictEqual( - '1.23 thousand', - ); + 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 convert the number to human readable format, with locale', () => { - expect(Num.forHumans(1200, { locale: 'fr' })).toStrictEqual('1,2 millier'); + 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 format the number to the given locale string', () => { - expect(Num.format(1000)).toStrictEqual('1,000'); - expect(Num.format(1000, { locale: 'fr' })).toStrictEqual('1 000'); - expect(Num.format(1200)).toStrictEqual('1,200'); + 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('converts the given number to the ordinal format', () => { - expect(Num.ordinal(1)).toStrictEqual('1st'); - expect(Num.ordinal(2)).toStrictEqual('2nd'); - expect(Num.ordinal(3)).toStrictEqual('3rd'); - expect(Num.ordinal(20)).toStrictEqual('20th'); + 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('converts the number to a percentage format with support for precision and locale config', () => { - expect(Num.percentage(10)).toStrictEqual('10.0%'); - expect(Num.percentage(10, { locale: 'fr' })).toStrictEqual('10,0 %'); - expect(Num.percentage(10.123, { precision: 2 })).toStrictEqual('10.12%'); + 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); }); }); diff --git a/lib/utils/tests/object.spec.ts b/lib/utils/tests/object.spec.ts index 6de865f..d5e6ec2 100644 --- a/lib/utils/tests/object.spec.ts +++ b/lib/utils/tests/object.spec.ts @@ -1,12 +1,220 @@ -import { Arr } from '../array'; +import { InvalidValue } from '../../exceptions'; +import { Obj } from '../object'; jest.mock('../../config/service'); -describe('Object Helpers', () => { +describe('Object Helper', () => { beforeEach(async () => {}); - it('should collapse a nested array in a single level array', () => { - const sample1 = ['a', ['b', ['c'], 1], 2]; - expect(Arr.collapse(sample1)).toStrictEqual(['a', 'b', 'c', 1, 2]); + // 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 }], + }, + }); }); }); diff --git a/packages/core/lib/console/consoleIO.ts b/packages/core/lib/console/consoleIO.ts index 42cbaf7..7249886 100644 --- a/packages/core/lib/console/consoleIO.ts +++ b/packages/core/lib/console/consoleIO.ts @@ -7,7 +7,7 @@ import { ConsoleLogger } from './logger'; export class ConsoleIO { schema: ArgumentParserOutput; rawValues: Record; - values: Record = { arguments: {}, options: {} }; + values = { arguments: {}, options: {} }; hasErrors: boolean; missingArguments: string[]; @@ -36,6 +36,14 @@ export class ConsoleIO { return this.values.options[key]; } + arguments(): Record { + return this.values.arguments; + } + + options(): Record { + return this.values.options; + } + handle(): ConsoleIO { this.schema = ArgumentParser.from(this.schemaString); this.values = { arguments: {}, options: {} }; @@ -68,16 +76,11 @@ export class ConsoleIO { this.validateArguments(); if (this.hasErrors) return this; - /** - * Parse options - */ for (const option of this.schema.options) { - const value = Obj.get(this.argv, option.name, ...option.alias); - if (value) { - this.values.options[option.name] = value; - } else { - this.values.options[option.name] = option.defaultValue; - } + const values = Object.values( + Obj.pick(this.argv, [option.name, ...option.alias]), + ); + this.values.options[option.name] = values[0] ? values[0] : undefined; } return this; diff --git a/packages/core/lib/utils/helpers.ts b/packages/core/lib/utils/helpers.ts index dc573aa..87a9b94 100644 --- a/packages/core/lib/utils/helpers.ts +++ b/packages/core/lib/utils/helpers.ts @@ -12,28 +12,14 @@ import { join } from 'path'; import { findProjectRoot } from './path'; export const isEmpty = (value: any) => { - if (Str.isString(value)) { - return value === ''; - } - - if (Arr.isArray(value)) { - return !value.length; - } - - if (Obj.isObj(value)) { - return Obj.isEmpty(value); - } - - if (Number.isNaN(value) || value === undefined) { - return true; - } - + if (Str.isString(value)) return value === ''; + if (Arr.isArray(value)) return !value.length; + if (Obj.isObj(value)) return Obj.isEmpty(value); + if (Number.isNaN(value) || value === undefined) return true; return false; }; -export const isBoolean = (value: any): boolean => { - return typeof value === 'boolean'; -}; +export const isBoolean = (value: any): boolean => typeof value === 'boolean'; export const toBoolean = (value: any) => { const val = String(value); diff --git a/packages/core/lib/utils/object.ts b/packages/core/lib/utils/object.ts index ace582d..2cbe3c9 100644 --- a/packages/core/lib/utils/object.ts +++ b/packages/core/lib/utils/object.ts @@ -102,26 +102,24 @@ export class Obj { return !Obj.isEmpty(obj); } - static get( + static get( obj: Record, key: string, - ...aliasKeys: string[] + defaultValue?: T, ): T { - const keys = [key, ...aliasKeys]; - for (const key of keys) { - if (key in obj) return obj[key]; - const splitKeys = key.split('.'); - if (!splitKeys.length) return; + if (key in obj) return obj[key]; + const splitKeys = key.split('.'); + if (!splitKeys.length) return; - if (Arr.isArray(obj[splitKeys[0]])) { - return Arr.get(obj[splitKeys[0]], splitKeys.slice(1).join('.')); - } + if (Arr.isArray(obj[splitKeys[0]])) { + return Arr.get(obj[splitKeys[0]], splitKeys.slice(1).join('.')); + } - if (Obj.isObj(obj[splitKeys[0]])) { - return Obj.get(obj[splitKeys[0]], splitKeys.slice(1).join('.')); - } + if (Obj.isObj(obj[splitKeys[0]])) { + return Obj.get(obj[splitKeys[0]], splitKeys.slice(1).join('.')); } - return undefined; + + return defaultValue; } static sort>(obj: T): T { diff --git a/tests/helpers/arrayHelper.spec.ts b/tests/helpers/arrayHelper.spec.ts deleted file mode 100644 index 44b9078..0000000 --- a/tests/helpers/arrayHelper.spec.ts +++ /dev/null @@ -1,100 +0,0 @@ -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 } }, - ]); - }); -}); diff --git a/tests/helpers/numberHelper.spec.ts b/tests/helpers/numberHelper.spec.ts deleted file mode 100644 index 1108b86..0000000 --- a/tests/helpers/numberHelper.spec.ts +++ /dev/null @@ -1,117 +0,0 @@ -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); - }); -}); diff --git a/tests/helpers/objectHelper.spec.ts b/tests/helpers/objectHelper.spec.ts deleted file mode 100644 index 4cc2a92..0000000 --- a/tests/helpers/objectHelper.spec.ts +++ /dev/null @@ -1,240 +0,0 @@ -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 57b504b61c23d939aeda941f689a7fbf09ed1d6a Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Jan 2025 20:01:25 +0000 Subject: [PATCH 6/8] refactor: remove unused code --- lib/config/__mocks__/service.ts | 3 - lib/config/service.ts | 0 lib/utils/tests/string.spec.ts | 268 ------------------ package-lock.json | 45 ++- .../core/tests/helpers/arrayHelper.spec.ts | 0 .../core/tests/helpers/numberHelper.spec.ts | 0 .../core/tests/helpers/objectHelper.spec.ts | 0 7 files changed, 42 insertions(+), 274 deletions(-) delete mode 100644 lib/config/__mocks__/service.ts delete mode 100644 lib/config/service.ts delete mode 100644 lib/utils/tests/string.spec.ts rename lib/utils/tests/array.spec.ts => packages/core/tests/helpers/arrayHelper.spec.ts (100%) rename lib/utils/tests/number.spec.ts => packages/core/tests/helpers/numberHelper.spec.ts (100%) rename lib/utils/tests/object.spec.ts => packages/core/tests/helpers/objectHelper.spec.ts (100%) diff --git a/lib/config/__mocks__/service.ts b/lib/config/__mocks__/service.ts deleted file mode 100644 index a4d1f8f..0000000 --- a/lib/config/__mocks__/service.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const IntentConfig = { - get: jest.fn(), -}; diff --git a/lib/config/service.ts b/lib/config/service.ts deleted file mode 100644 index e69de29..0000000 diff --git a/lib/utils/tests/string.spec.ts b/lib/utils/tests/string.spec.ts deleted file mode 100644 index 143e331..0000000 --- a/lib/utils/tests/string.spec.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { Str } from '../string'; - -jest.mock('../../config/service'); - -describe('String Helper', () => { - beforeEach(async () => {}); - - it('returns the part of the string present after the passed delimiter', () => { - const string = Str.after('Hello, World!!', ','); - expect(string).toBe(' World!!'); - }); - - it('returns the part of the string befored the passed delimiter', () => { - const string = Str.before('Hello, World!!', ','); - expect(string).toBe('Hello'); - }); - - it('compares the string with pattern', () => { - const string = 'users:create'; - const patterns = { 'users:create': true, '*:create': true, admin: false }; - for (const pattern in patterns) { - expect(Str.is(string, pattern)).toBe(patterns[pattern]); - } - }); - - it('returns the string present between the specified stat and end delimiters', () => { - const sentence = 'The quick brown fox jumps over a lazy dog.'; - const result = Str.between(sentence, 'brown', 'jumps'); - expect(result).toBe(' fox '); - }); - - it('converts the string to a camelCase', () => { - const samples = { - intent_js: 'intentJs', - 'quick brown fox jumps': 'quickBrownFoxJumps', - // "Hey_there, What's up?": 'heyThereWhatSUp', - }; - for (const str in samples) { - expect(Str.camel(str)).toBe(samples[str]); - } - }); - - it('check if string contains the specified string', () => { - const samples = { over: true, over2: false }; - const sentence = 'The quick brown fox jumps over a lazy dog.'; - - for (const sample in samples) { - expect(Str.contains(sentence, sample)).toBe(samples[sample]); - } - }); - - it('check if string contains all specified strings', () => { - const sentence = 'The quick brown fox jumps over a lazy dog.'; - expect(Str.containsAll(sentence, ['fox', 'dog'])).toBe(true); - expect(Str.containsAll(sentence, ['fox', 'whale'])).toBe(false); - }); - - it('returns true if string ends with the specified delimitter', () => { - const sentence = 'The quick brown fox jumps over a lazy dog.'; - expect(Str.endsWith(sentence, 'dog.')).toBe(true); - }); - - it('returns false if string ends with the specified delimitter', () => { - const sentence = 'The quick brown fox jumps over a lazy dog.'; - expect(Str.endsWith(sentence, 'dog2.')).toBe(false); - }); - - it('should return the string to headline', () => { - const sentence = 'Is this real?'; - expect(Str.headline(sentence)).toBe('Is This Real?'); - }); - - it('should validate if the string is email or not', () => { - const samples = { - 'hi@tryintent.com': true, - 'tryintent.com': false, - }; - for (const email in samples) { - expect(Str.isEmail(email)).toStrictEqual(samples[email]); - } - }); - - it('should validate if the given string is a valid JSON or not', () => { - const samples = { - '{"name": "Intent"}': true, - '{"name": "Intent"': false, - }; - - for (const json in samples) { - expect(Str.isJson(json)).toStrictEqual(samples[json]); - } - }); - - it('should validate if the string is a valid URL or not', () => { - const samples = { - 'https://tryintent.com': true, - 'tryintent.com': true, - 'docs.tryintent.com': true, - 'http2://tryintent.com': false, - }; - - for (const url in samples) { - expect(Str.isUrl(url)).toStrictEqual(samples[url]); - } - }); - - it('should validate if the string is valid ulid or not', () => { - const samples = { - ABCDOKMK: false, - '01ARZ3NDEKTSV4RRFFQ69G5FAV': true, - }; - for (const ulid in samples) { - expect(Str.isUlid(ulid)).toStrictEqual(samples[ulid]); - } - }); - - it('should transform the string to kebab case', () => { - const samples = { - intent_js: 'intent-js', - 'quick brown fox jumps': 'quick-brown-fox-jumps', - "Hey_there, What's up?": 'hey-there-what-s-up', - }; - for (const str in samples) { - expect(Str.kebab(str)).toStrictEqual(samples[str]); - } - }); - - it('should convert the first character of a string to lowercase', () => { - const samples = { - INTENT: 'iNTENT', - Intent: 'intent', - }; - for (const str in samples) { - expect(Str.lcfirst(str)).toStrictEqual(samples[str]); - } - }); - - it('returns the correct length of a string', () => { - expect(Str.len('intent')).toStrictEqual(6); - expect(Str.len(undefined)).toStrictEqual(0); - }); - - it('should returns only `n` length of character for a given string', () => { - const sentence = 'The quick brown fox jumps over a lazy dog.'; - expect(Str.limit(sentence, 15)).toStrictEqual('The quick brown...'); - expect(Str.limit(sentence, 15, '!!!')).toStrictEqual('The quick brown!!!'); - expect(Str.limit(sentence, 500)).toStrictEqual(sentence); - }); - - it('should converts the string to lowercase', () => { - expect(Str.lower('HEY THERE!!')).toStrictEqual('hey there!!'); - }); - - it('should mask the string after certain characters', () => { - expect(Str.mask('hi@tryintent.com', '*', 7)).toStrictEqual( - 'hi@tryi*********', - ); - }); - - it('should pad both ends of the string with character to a defined length', () => { - expect(Str.padBoth('intent', 10, '--')).toStrictEqual('--intent--'); - }); - - it('should only pad left of the string with character to a defined length', () => { - expect(Str.padLeft('intent', 10, '--')).toStrictEqual('----intent'); - }); - - it('should only pad right of the string with character to a defined length', () => { - expect(Str.padRight('intent', 10, '--')).toStrictEqual('intent----'); - }); - - it('should remove the given substring in a given string', () => { - const sentence = 'The quick brown fox jumps over a lazy dog.'; - expect(Str.remove(sentence, 'quick ')).toStrictEqual( - 'The brown fox jumps over a lazy dog.', - ); - expect(Str.remove(sentence, ' ')).toStrictEqual( - 'Thequickbrownfoxjumpsoveralazydog.', - ); - }); - - it('should repeat the given string defined number of times.', () => { - expect(Str.repeat('chug ', 5)).toStrictEqual('chug chug chug chug chug '); - }); - - it('should replace the given string with another string', () => { - expect(Str.replace('I hate intent!', 'hate', 'love')).toStrictEqual( - 'I love intent!', - ); - expect(Str.replace('I Hate intent!', 'hate', 'love', true)).toStrictEqual( - 'I love intent!', - ); - }); - - it('should replace the matching string sequentially with the string array', () => { - const str = 'I will be there between ? and ?'; - expect(Str.replaceArray(str, '?', ['8:30', '9:30PM'])).toStrictEqual( - 'I will be there between 8:30 and 9:30PM', - ); - }); - - it('should only replace the first matching string with the the replacement string', () => { - const sentence = 'the quick brown fox jumps over the lazy dog.'; - expect(Str.replaceFirst(sentence, 'the', 'a')).toStrictEqual( - 'a quick brown fox jumps over the lazy dog.', - ); - }); - - it('should only replace the last matching string with the the replacement string', () => { - const sentence = 'the quick brown fox jumps over the lazy dog.'; - expect(Str.replaceLast(sentence, 'the', 'a')).toStrictEqual( - 'the quick brown fox jumps over a lazy dog.', - ); - }); - - it('should correctly reverse the given string', () => { - expect(Str.reverse('wtf! why reverse?')).toStrictEqual('?esrever yhw !ftw'); - }); - - it('should pluralize the sentence', () => { - const string = `Vinayak ${Str.pluralize('have')} 5 ${Str.pluralize( - 'apple', - )}.`; - expect(string).toBe('Vinayak has 5 apples.'); - }); - - it('should replace using string', () => { - const string = 'vinayak don'; - const find = 'don'; - const replace = 'sarawagi'; - expect(Str.replace(string, find, replace)).toBe('vinayak sarawagi'); - }); - - it('should replace using regex', () => { - const string = 'vinayak don'; - const find = 'don'; - const replace = 'sarawagi'; - expect(Str.replace(string, find, replace)).toBe('vinayak sarawagi'); - }); - - it('should replace all occurences using string', () => { - const string = 'vinayak don don don don'; - const find = 'don'; - const replace = 'sarawagi'; - expect(Str.replace(string, find, replace)).toBe( - 'vinayak sarawagi sarawagi sarawagi sarawagi', - ); - }); - - it('should replace all occurences using regex', () => { - const string = 'Virat Kohli says Ben Stokes'; - const replacements = { - 'Ben Stokes': 'OUT!!', - }; - expect(Str.swap(string, replacements)).toBe('Virat Kohli says OUT!!'); - }); - - it('should convert to snake case', () => { - const string = 'IntentJs - For the devs_whoHaveTheIntent'; - expect(Str.snake(string)).toBe( - 'intent_js_for_the_devs_who_have_the_intent', - ); - }); - - it('should singularize', () => { - expect(Str.singular('indices')).toBe('index'); - }); -}); diff --git a/package-lock.json b/package-lock.json index df66d30..eaf801e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,11 +69,36 @@ "typescript": "^5.1.3" } }, + "integrations/sample-app/node_modules/@intentjs/cli": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@intentjs/cli/-/cli-0.0.7.tgz", + "integrity": "sha512-mWH2P/OObjvF9rPx9QSBngR6J5tMIDd2nZuN4Gapbrh+iF+Vd0Q+ehBBjRKpuXEx3+dNLdENGa4TSHGSlsV++g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@swc/cli": "^0.5.2", + "@swc/core": "^1.10.0", + "chokidar": "^3.5.1", + "commander": "^12.1.0", + "enquirer": "^2.4.1", + "fs-extra": "^11.2.0", + "picocolors": "^1.1.0", + "radash": "^12.1.0", + "tree-kill": "^1.2.2", + "typescript": "^5.6.2" + }, + "bin": { + "intent": "bin/intent.js" + }, + "engines": { + "node": ">= 16.14" + } + }, "integrations/sample-app/node_modules/@intentjs/cli/node_modules/@swc/cli": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.5.2.tgz", "integrity": "sha512-ul2qIqjM5bfe9zWLqFDmHZCf9HXXSZZAlZLe4czn+lH4PewO+OWZnQcYCscnJKlbx6MuWjzXVR7gkspjNEJwJA==", - "extraneous": true, + "dev": true, "license": "MIT", "dependencies": { "@swc/counter": "^0.1.3", @@ -104,6 +129,20 @@ } } }, + "integrations/sample-app/node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "license": "Apache-2.0", @@ -19025,7 +19064,7 @@ }, "packages/cli": { "name": "@intentjs/cli", - "version": "0.0.7", + "version": "0.0.9", "license": "MIT", "dependencies": { "@clack/prompts": "^0.9.0", @@ -19209,7 +19248,7 @@ }, "packages/core": { "name": "@intentjs/core", - "version": "0.1.40", + "version": "0.1.41", "license": "MIT", "dependencies": { "@intentjs/hyper-express": "^0.0.5", diff --git a/lib/utils/tests/array.spec.ts b/packages/core/tests/helpers/arrayHelper.spec.ts similarity index 100% rename from lib/utils/tests/array.spec.ts rename to packages/core/tests/helpers/arrayHelper.spec.ts diff --git a/lib/utils/tests/number.spec.ts b/packages/core/tests/helpers/numberHelper.spec.ts similarity index 100% rename from lib/utils/tests/number.spec.ts rename to packages/core/tests/helpers/numberHelper.spec.ts diff --git a/lib/utils/tests/object.spec.ts b/packages/core/tests/helpers/objectHelper.spec.ts similarity index 100% rename from lib/utils/tests/object.spec.ts rename to packages/core/tests/helpers/objectHelper.spec.ts From adf90f741a79f7209d16c92d04f3943ab3c2fb29 Mon Sep 17 00:00:00 2001 From: Piyush Chhabra Date: Sat, 18 Jan 2025 07:13:29 +0000 Subject: [PATCH 7/8] test: add helper tests --- packages/core/tests/helpers/arrayHelper.spec.ts | 4 ++-- packages/core/tests/helpers/numberHelper.spec.ts | 4 ++-- packages/core/tests/helpers/objectHelper.spec.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/tests/helpers/arrayHelper.spec.ts b/packages/core/tests/helpers/arrayHelper.spec.ts index 8ddf9d8..37ca7f0 100644 --- a/packages/core/tests/helpers/arrayHelper.spec.ts +++ b/packages/core/tests/helpers/arrayHelper.spec.ts @@ -1,6 +1,6 @@ -import { Arr } from '../array'; +import { Arr } from '../../lib'; -jest.mock('../../config/service'); +jest.mock('../../lib/config/service'); describe('Array Helper', () => { beforeEach(async () => {}); diff --git a/packages/core/tests/helpers/numberHelper.spec.ts b/packages/core/tests/helpers/numberHelper.spec.ts index 9260c72..99f15d9 100644 --- a/packages/core/tests/helpers/numberHelper.spec.ts +++ b/packages/core/tests/helpers/numberHelper.spec.ts @@ -1,6 +1,6 @@ -import { Num } from '../number'; +import { Num } from '../../lib'; -jest.mock('../../config/service'); +jest.mock('../../../lib/config/service'); describe('Numbers Helper', () => { beforeEach(async () => {}); diff --git a/packages/core/tests/helpers/objectHelper.spec.ts b/packages/core/tests/helpers/objectHelper.spec.ts index d5e6ec2..c76019d 100644 --- a/packages/core/tests/helpers/objectHelper.spec.ts +++ b/packages/core/tests/helpers/objectHelper.spec.ts @@ -1,5 +1,5 @@ -import { InvalidValue } from '../../exceptions'; -import { Obj } from '../object'; +import { InvalidValue } from '../../lib'; +import { Obj } from '../../lib'; jest.mock('../../config/service'); From 8cc6a3cc0737fdcb8e70612a2056da8c7b3cc020 Mon Sep 17 00:00:00 2001 From: Piyush Chhabra Date: Sat, 18 Jan 2025 12:49:31 +0000 Subject: [PATCH 8/8] fix: config service import --- packages/core/tests/helpers/arrayHelper.spec.ts | 4 ---- packages/core/tests/helpers/numberHelper.spec.ts | 2 +- packages/core/tests/helpers/objectHelper.spec.ts | 7 +------ 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/core/tests/helpers/arrayHelper.spec.ts b/packages/core/tests/helpers/arrayHelper.spec.ts index 37ca7f0..51c223e 100644 --- a/packages/core/tests/helpers/arrayHelper.spec.ts +++ b/packages/core/tests/helpers/arrayHelper.spec.ts @@ -5,10 +5,6 @@ jest.mock('../../lib/config/service'); describe('Array Helper', () => { beforeEach(async () => {}); - // it('should throw exception', () => { - // const arr = {}; - // expect(Arr.toObj(arr as [], [])).toThrow(InvalidValue); - // }); it('should return object', () => { const arr = [ diff --git a/packages/core/tests/helpers/numberHelper.spec.ts b/packages/core/tests/helpers/numberHelper.spec.ts index 99f15d9..6733fba 100644 --- a/packages/core/tests/helpers/numberHelper.spec.ts +++ b/packages/core/tests/helpers/numberHelper.spec.ts @@ -1,6 +1,6 @@ import { Num } from '../../lib'; -jest.mock('../../../lib/config/service'); +jest.mock('../../lib/config/service'); describe('Numbers Helper', () => { beforeEach(async () => {}); diff --git a/packages/core/tests/helpers/objectHelper.spec.ts b/packages/core/tests/helpers/objectHelper.spec.ts index c76019d..146dbf7 100644 --- a/packages/core/tests/helpers/objectHelper.spec.ts +++ b/packages/core/tests/helpers/objectHelper.spec.ts @@ -1,16 +1,11 @@ import { InvalidValue } from '../../lib'; import { Obj } from '../../lib'; -jest.mock('../../config/service'); +jest.mock('../../lib/config/service'); 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' }] },