diff --git a/src/modules/helpers/index.ts b/src/modules/helpers/index.ts index 4f1c164d821..b3d4bce9f0f 100644 --- a/src/modules/helpers/index.ts +++ b/src/modules/helpers/index.ts @@ -622,6 +622,37 @@ export class HelpersModule { return arrayCopy.slice(min); } + /** + * Returns a random value from an Enum object. + * + * This does the same as `objectValue` except that it ignores (the values assigned to) the numeric keys added for TypeScript enums. + * + * @template EnumType Type of generic enums, automatically inferred by TypeScript. + * @param enumObject Enum to pick the value from. + * + * @example + * enum Color { Red, Green, Blue } + * faker.helpers.enumValue(Color) // 1 (Green) + * + * enum Direction { North = 'North', South = 'South'} + * faker.helpers.enumValue(Direction) // 'South' + * + * enum HttpStatus { Ok = 200, Created = 201, BadRequest = 400, Unauthorized = 401 } + * faker.helpers.enumValue(HttpStatus) // 200 (Ok) + * + * @since 8.0.0 + */ + enumValue>( + enumObject: EnumType + ): EnumType[keyof EnumType] { + // ignore numeric keys added by TypeScript + const keys: Array = Object.keys(enumObject).filter((key) => + isNaN(Number(key)) + ); + const randomKey = this.arrayElement(keys); + return enumObject[randomKey]; + } + /** * Generator for combining faker methods based on a static string input. * diff --git a/test/__snapshots__/helpers.spec.ts.snap b/test/__snapshots__/helpers.spec.ts.snap index fe9a22884ef..6eb28ad19aa 100644 --- a/test/__snapshots__/helpers.spec.ts.snap +++ b/test/__snapshots__/helpers.spec.ts.snap @@ -36,6 +36,14 @@ exports[`helpers > 42 > arrayElements > with array and count range 1`] = ` ] `; +exports[`helpers > 42 > enumValue > with default enum 1`] = `1`; + +exports[`helpers > 42 > enumValue > with enum starting from some index 1`] = `400`; + +exports[`helpers > 42 > enumValue > with mixed enum 1`] = `1`; + +exports[`helpers > 42 > enumValue > with string enum 1`] = `"Brazil"`; + exports[`helpers > 42 > fake > with a dynamic template 1`] = `"my string: Cky2eiXX/J"`; exports[`helpers > 42 > fake > with a static template 1`] = `"my test string"`; @@ -235,6 +243,14 @@ exports[`helpers > 1211 > arrayElements > with array and count range 1`] = ` ] `; +exports[`helpers > 1211 > enumValue > with default enum 1`] = `2`; + +exports[`helpers > 1211 > enumValue > with enum starting from some index 1`] = `401`; + +exports[`helpers > 1211 > enumValue > with mixed enum 1`] = `"Bar"`; + +exports[`helpers > 1211 > enumValue > with string enum 1`] = `"United States of America"`; + exports[`helpers > 1211 > fake > with a dynamic template 1`] = `"my string: wKti5-}$_/"`; exports[`helpers > 1211 > fake > with a static template 1`] = `"my test string"`; @@ -427,6 +443,14 @@ exports[`helpers > 1337 > arrayElements > with array and count range 1`] = ` ] `; +exports[`helpers > 1337 > enumValue > with default enum 1`] = `0`; + +exports[`helpers > 1337 > enumValue > with enum starting from some index 1`] = `200`; + +exports[`helpers > 1337 > enumValue > with mixed enum 1`] = `1`; + +exports[`helpers > 1337 > enumValue > with string enum 1`] = `"Brazil"`; + exports[`helpers > 1337 > fake > with a dynamic template 1`] = `"my string: 9U/4:SK$>6"`; exports[`helpers > 1337 > fake > with a static template 1`] = `"my test string"`; diff --git a/test/helpers.spec.ts b/test/helpers.spec.ts index 2334c2a20de..2fa08bea1ad 100644 --- a/test/helpers.spec.ts +++ b/test/helpers.spec.ts @@ -55,6 +55,37 @@ describe('helpers', () => { t.it('noArgs').it('with array', 'Hello World!'.split('')); }); + t.describe('enumValue', (t) => { + enum Color { + Red, + Green, + Blue, + } + + enum HttpStatus { + Ok = 200, + BadRequest = 400, + Unauthorized = 401, + } + + enum Country { + BR = 'Brazil', + USA = 'United States of America', + } + + enum MixedFoo { + Foo = 0, + Bar = 1, + FooName = 'Foo', + BarName = 'Bar', + } + + t.it('with default enum', Color) + .it('with enum starting from some index', HttpStatus) + .it('with string enum', Country) + .it('with mixed enum', MixedFoo); + }); + t.describe('weightedArrayElement', (t) => { t.it('with array', [ { weight: 5, value: 'sunny' }, @@ -159,6 +190,50 @@ describe('helpers', () => { }); }); + describe('enumValue', () => { + enum ColorValueEnum { + Red, + Green, + Blue, + } + enum ColorValueWithStartIndexEnum { + Red = 3, + Green, + Blue, + } + enum ColorStringEnum { + Red = 'RED', + Green = 'GREEN', + Blue = 'BLUE', + } + enum FooMixedEnum { + Foo = 0, + Bar = 1, + StrFoo = 'FOO', + StrBar = 'BAR', + } + + it('should return a value from a numeric enum', () => { + const actual = faker.helpers.enumValue(ColorValueEnum); + expect([0, 1, 2]).toContain(actual); + }); + + it('should return a value from a numeric enum that first value is not 0', () => { + const actual = faker.helpers.enumValue(ColorValueWithStartIndexEnum); + expect([3, 4, 5]).toContain(actual); + }); + + it('should return a value from a string enum', () => { + const actual = faker.helpers.enumValue(ColorStringEnum); + expect(['RED', 'GREEN', 'BLUE']).toContain(actual); + }); + + it('should return a value from a mixed enum', () => { + const actual = faker.helpers.enumValue(FooMixedEnum); + expect([0, 1, 'FOO', 'BAR']).toContain(actual); + }); + }); + describe('weightedArrayElement', () => { it('should return a weighted random element in the array', () => { const testArray = [