Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: separate methods for object key value #503

Merged
merged 9 commits into from
Apr 30, 2022
13 changes: 6 additions & 7 deletions src/finance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class Finance {
* faker.finance.currencyCode() // 'USD'
*/
currencyCode(): string {
return this.faker.random.objectElement(
return this.faker.random.objectValue(
this.faker.definitions.finance.currency
)['code'];
}
Expand All @@ -183,10 +183,9 @@ export class Finance {
* faker.finance.currencyName() // 'US Dollar'
*/
currencyName(): string {
return this.faker.random.objectElement(
this.faker.definitions.finance.currency,
'key'
);
return this.faker.random.objectKey(
this.faker.definitions.finance.currency
) as string;
}

/**
Expand All @@ -198,7 +197,7 @@ export class Finance {
currencySymbol(): string {
let symbol: string;
while (!symbol) {
symbol = this.faker.random.objectElement(
symbol = this.faker.random.objectValue(
this.faker.definitions.finance.currency
)['symbol'];
}
Expand Down Expand Up @@ -265,7 +264,7 @@ export class Finance {
} else {
// Choose a random provider
// Credit cards are in an object structure
const formats = this.faker.random.objectElement(localeFormat, 'value'); // There could be multiple formats
const formats = this.faker.random.objectValue(localeFormat); // There could be multiple formats
format = this.faker.random.arrayElement(formats);
}
format = format.replace(/\//g, '');
Expand Down
107 changes: 96 additions & 11 deletions src/random.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,25 +161,42 @@ export class Random {
}

/**
* Returns a random key or value from given object.
* Returns a random key from given object.
*
* @template T The type of `Record` to pick from.
* @template K The keys of `T`.
* @param object The object to get the keys or values from.
* @param object The object to get the keys from.
* @param field If this is set to `'key'`, this method will a return a random key of the given instance.
* If this is set to `'value'`, this method will a return a random value of the given instance.
* Defaults to `'value'`.
*
* @see faker.random.objectKey()
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
*
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'key') // 'keyB'
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
ST-DDT marked this conversation as resolved.
Show resolved Hide resolved
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object: T,
field: 'key'
): K;
/**
* Returns a random value from given object.
*
* @template T The type of `Record` to pick from.
* @template K The keys of `T`.
* @param object The object to get the values from.
* @param field If this is set to `'value'`, this method will a return a random value of the given instance.
*
* @see faker.random.objectValue()
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
*
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object: T,
field?: unknown
Expand All @@ -194,24 +211,92 @@ export class Random {
* If this is set to `'value'`, this method will a return a random value of the given instance.
* Defaults to `'value'`.
*
* @see faker.random.objectKey()
* @see faker.random.objectValue()
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
*
ST-DDT marked this conversation as resolved.
Show resolved Hide resolved
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'key') // 'keyB'
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object: T,
object?: T,
field?: 'key' | 'value'
): K | T[K];
/**
* Returns a random key or value from given object.
*
* @template T The type of `Record` to pick from.
* @template K The keys of `T`.
* @param object The object to get the keys or values from.
* @param field If this is set to `'key'`, this method will a return a random key of the given instance.
* If this is set to `'value'`, this method will a return a random value of the given instance.
* Defaults to `'value'`.
*
* @see faker.random.objectKey()
* @see faker.random.objectValue()
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
*
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'key') // 'keyB'
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object = { foo: 'bar', too: 'car' } as unknown as T,
field = 'value'
object: T = { foo: 'bar', too: 'car' } as unknown as T,
field: 'key' | 'value' = 'value'
): K | T[K] {
const useKey = field === 'key';
deprecated({
deprecated: `faker.random.objectElement(${useKey ? "obj, 'key'" : ''})`,
proposed: `faker.random.object${useKey ? 'Key' : 'Value'}()`,
since: 'v6.3.0',
until: 'v7.0.0',
});
return field === 'key'
? (this.faker.random.objectKey(object) as K)
: (this.faker.random.objectValue(object) as T[K]);
}

/**
* Returns a random key from given object.
*
* @param object The optional object to be used. If not specified, it defaults to `{ foo: 'bar', too: 'car' }`.
*
* @example
* faker.random.objectKey() // 'foo'
* faker.random.objectKey({ myProperty: 'myValue' }) // 'myProperty'
*/
objectKey<T extends Record<string, unknown>>(
object: T = { foo: 'bar', too: 'car' } as unknown as T
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
): keyof T {
const array: Array<keyof T> = Object.keys(object);
const key = this.arrayElement(array);
const key = this.faker.random.arrayElement(array);

return key;
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Returns a random value from given object.
*
* @param object The optional object to be used. If not specified, it defaults to `{ foo: 'bar', too: 'car' }`.
*
* @example
* faker.random.objectValue() // 'bar'
* faker.random.objectValue({ myProperty: 'myValue' }) // 'myValue'
*/
objectValue<T extends Record<string, unknown>>(
object: T = { foo: 'bar', too: 'car' } as unknown as T
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
): T[keyof T] {
const key = this.faker.random.objectKey(object);
const value = object[key];

return field === 'key' ? (key as K) : (object[key] as T[K]);
return value;
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
40 changes: 40 additions & 0 deletions test/random.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ describe('random', () => {

describe('objectElement', () => {
it('should return a random value', () => {
const spy = vi.spyOn(console, 'warn');

const testObject = {
hello: 'to',
you: 'my',
Expand All @@ -167,9 +169,16 @@ describe('random', () => {
const actual = faker.random.objectElement(testObject);

expect(Object.values(testObject)).toContain(actual);
expect(spy).toHaveBeenCalledWith(
`[@faker-js/faker]: faker.random.objectElement() is deprecated since v6.3.0 and will be removed in v7.0.0. Please use faker.random.objectValue() instead.`
);

spy.mockRestore();
});

it('should return a random key', () => {
const spy = vi.spyOn(console, 'warn');

const testObject = {
hello: 'to',
you: 'my',
Expand All @@ -178,6 +187,37 @@ describe('random', () => {
const actual = faker.random.objectElement(testObject, 'key');

expect(Object.keys(testObject)).toContain(actual);
expect(spy).toHaveBeenCalledWith(
`[@faker-js/faker]: faker.random.objectElement(obj, 'key') is deprecated since v6.3.0 and will be removed in v7.0.0. Please use faker.random.objectKey() instead.`
);

spy.mockRestore();
});
});

describe('objectKey', () => {
it('should return a random key', () => {
const testObject = {
hello: 'to',
you: 'my',
friend: '!',
};
const actual = faker.random.objectKey(testObject);

expect(Object.keys(testObject)).toContain(actual);
});
});

describe('objectValue', () => {
it('should return a random value', () => {
const testObject = {
hello: 'to',
you: 'my',
friend: '!',
};
const actual = faker.random.objectValue(testObject);

expect(Object.values(testObject)).toContain(actual);
});
});

Expand Down