aboutsummaryrefslogtreecommitdiff
path: root/src/name.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/name.ts')
-rw-r--r--src/name.ts294
1 files changed, 144 insertions, 150 deletions
diff --git a/src/name.ts b/src/name.ts
index 6b727569..8fac27c4 100644
--- a/src/name.ts
+++ b/src/name.ts
@@ -1,5 +1,83 @@
import type { Faker } from '.';
+export enum Gender {
+ female = 'female',
+ male = 'male',
+}
+
+// TODO @Shinigami92 21-03-2022: Remove 0 and 1 in v7
+export type GenderType = 'female' | 'male' | 0 | 1;
+
+/**
+ * Normalize gender.
+ *
+ * @param gender Gender.
+ * @returns Normalized gender.
+ */
+function normalizeGender(
+ gender?: GenderType
+): Exclude<GenderType, number> | undefined {
+ if (gender == null || typeof gender === 'string') {
+ // TODO @Shinigami92 21-03-2022: Cast can be removed when we set `strict: true`
+ return gender as Exclude<GenderType, number>;
+ }
+
+ const normalizedGender = gender === 0 ? 'male' : 'female';
+
+ console.warn(
+ `Deprecation Warning: Please use '${normalizedGender}' for gender instead of ${gender}`
+ );
+
+ return normalizedGender;
+}
+
+/**
+ * Select a definition based on given gender.
+ *
+ * @param faker Faker instance.
+ * @param gender Gender.
+ * @param param2 Definitions.
+ * @param param2.generic Non-gender definitions.
+ * @param param2.female Female definitions.
+ * @param param2.male Male definitions.
+ * @returns Definition based on given gender.
+ */
+function selectDefinition(
+ faker: Faker,
+ gender: GenderType | undefined,
+ // TODO christopher 21-03-2022: Remove fallback empty object when `strict: true`
+ {
+ generic,
+ female,
+ male,
+ }: { generic?: string[]; female?: string[]; male?: string[] } = {}
+) {
+ const normalizedGender = normalizeGender(gender);
+
+ let values: string[] | undefined;
+ switch (normalizedGender) {
+ case 'female':
+ values = female;
+ break;
+ case 'male':
+ values = male;
+ break;
+ default:
+ values = generic;
+ break;
+ }
+
+ if (values == null) {
+ if (female != null && male != null) {
+ values = faker.random.arrayElement([female, male]);
+ } else {
+ values = generic;
+ }
+ }
+
+ return faker.random.arrayElement(values);
+}
+
/**
* Module to generate people's names and titles.
*/
@@ -18,131 +96,66 @@ export class Name {
* Returns a random first name.
*
* @param gender The optional gender to use.
- * Can be either `'male'` (or `0`) or `'female'` (or `1`).
+ * Can be either `'female'` or `'male'`.
*
* @example
* faker.name.firstName() // 'Antwan'
* faker.name.firstName("female") // 'Victoria'
- * faker.name.firstName(1) // 'Ashley'
* faker.name.firstName("male") // 'Tom'
- * faker.name.firstName(0) // 'Ismael'
*/
- firstName(gender?: string | number): string {
- if (
- typeof this.faker.definitions.name.male_first_name !== 'undefined' &&
- typeof this.faker.definitions.name.female_first_name !== 'undefined'
- ) {
- // some locale datasets ( like ru ) have first_name split by gender. since the name.first_name field does not exist in these datasets,
- // we must randomly pick a name from either gender array so faker.name.firstName will return the correct locale data ( and not fallback )
-
- if (typeof gender === 'string') {
- if (gender.toLowerCase() === 'male') {
- gender = 0;
- } else if (gender.toLowerCase() === 'female') {
- gender = 1;
- }
- }
-
- if (typeof gender !== 'number') {
- if (typeof this.faker.definitions.name.first_name === 'undefined') {
- gender = this.faker.datatype.number(1);
- } else {
- // Fall back to non-gendered names if they exist and gender wasn't specified
- return this.faker.random.arrayElement(
- this.faker.definitions.name.first_name
- );
- }
- }
- if (gender === 0) {
- return this.faker.random.arrayElement(
- this.faker.definitions.name.male_first_name
- );
- } else {
- return this.faker.random.arrayElement(
- this.faker.definitions.name.female_first_name
- );
- }
- }
+ firstName(gender?: GenderType): string {
+ const { first_name, female_first_name, male_first_name } =
+ this.faker.definitions.name;
- return this.faker.random.arrayElement(
- this.faker.definitions.name.first_name
- );
+ return selectDefinition(this.faker, gender, {
+ generic: first_name,
+ female: female_first_name,
+ male: male_first_name,
+ });
}
/**
* Returns a random last name.
*
* @param gender The optional gender to use.
- * Can be either `'male'` (or `0`) or `'female'` (or `1`).
+ * Can be either `'female'` or `'male'`.
*
* @example
* faker.name.lastName() // 'Hauck'
* faker.name.lastName("female") // 'Grady'
- * faker.name.lastName(1) // 'Kshlerin'
* faker.name.lastName("male") // 'Barton'
- * faker.name.lastName(0) // 'Lockman'
*/
- lastName(gender?: string | number): string {
- if (
- typeof this.faker.definitions.name.male_last_name !== 'undefined' &&
- typeof this.faker.definitions.name.female_last_name !== 'undefined'
- ) {
- // some locale datasets ( like ru ) have last_name split by gender. i have no idea how last names can have genders, but also i do not speak russian
- // see above comment of firstName method
- if (typeof gender !== 'number') {
- gender = this.faker.datatype.number(1);
- }
- if (gender === 0) {
- return this.faker.random.arrayElement(
- this.faker.locales[this.faker.locale].name.male_last_name
- );
- } else {
- return this.faker.random.arrayElement(
- this.faker.locales[this.faker.locale].name.female_last_name
- );
- }
- }
+ lastName(gender?: GenderType): string {
+ const { last_name, female_last_name, male_last_name } =
+ this.faker.definitions.name;
- return this.faker.random.arrayElement(
- this.faker.definitions.name.last_name
- );
+ return selectDefinition(this.faker, gender, {
+ generic: last_name,
+ female: female_last_name,
+ male: male_last_name,
+ });
}
/**
* Returns a random middle name.
*
* @param gender The optional gender to use.
- * Can be either `'male'` (or `0`) or `'female'` (or `1`).
+ * Can be either `'female'` or `'male'`.
*
* @example
* faker.name.middleName() // 'Доброславівна'
* faker.name.middleName("female") // 'Анастасівна'
- * faker.name.middleName(1) // 'Анатоліївна'
* faker.name.middleName("male") // 'Вікторович'
- * faker.name.middleName(0) // 'Стефанович'
*/
- middleName(gender?: string | number): string {
- if (
- typeof this.faker.definitions.name.male_middle_name !== 'undefined' &&
- typeof this.faker.definitions.name.female_middle_name !== 'undefined'
- ) {
- if (typeof gender !== 'number') {
- gender = this.faker.datatype.number(1);
- }
- if (gender === 0) {
- return this.faker.random.arrayElement(
- this.faker.definitions.name.male_middle_name
- );
- } else {
- return this.faker.random.arrayElement(
- this.faker.definitions.name.female_middle_name
- );
- }
- }
+ middleName(gender?: GenderType): string {
+ const { middle_name, female_middle_name, male_middle_name } =
+ this.faker.definitions.name;
- return this.faker.random.arrayElement(
- this.faker.definitions.name.middle_name
- );
+ return selectDefinition(this.faker, gender, {
+ generic: middle_name,
+ female: female_middle_name,
+ male: male_middle_name,
+ });
}
/**
@@ -151,35 +164,29 @@ export class Name {
* @param firstName The optional first name to use. If not specified a random one will be chosen.
* @param lastName The optional last name to use. If not specified a random one will be chosen.
* @param gender The optional gender to use.
- * Can be either `'male'` (or `0`) or `'female'` (or `1`).
+ * Can be either `'female'` or `'male'`.
*
* @example
* faker.name.findName() // 'Allen Brown'
* faker.name.findName('Joann') // 'Joann Osinski'
- * faker.name.findName('Marcella', '', 1) // 'Mrs. Marcella Huels'
+ * faker.name.findName('Marcella', '', 'female') // 'Mrs. Marcella Huels'
* faker.name.findName(undefined, 'Beer') // 'Mr. Alfonso Beer'
- * faker.name.findName(undefined, undefined, 0) // 'Fernando Schaefer'
+ * faker.name.findName(undefined, undefined, 'male') // 'Fernando Schaefer'
*/
- findName(
- firstName?: string,
- lastName?: string,
- gender?: string | number
- ): string {
- const r = this.faker.datatype.number(8);
+ findName(firstName?: string, lastName?: string, gender?: GenderType): string {
+ const variant = this.faker.datatype.number(8);
let prefix = '';
let suffix = '';
- // in particular locales first and last names split by gender,
- // thus we keep consistency by passing 0 as male and 1 as female
-
- if (typeof gender !== 'number') {
- gender = this.faker.datatype.number(1);
- }
+ const normalizedGender: Exclude<GenderType, number> =
+ normalizeGender(gender) ??
+ this.faker.random.arrayElement(['female', 'male']);
- firstName = firstName || this.faker.name.firstName(gender);
- lastName = lastName || this.faker.name.lastName(gender);
+ firstName = firstName || this.faker.name.firstName(normalizedGender);
+ lastName = lastName || this.faker.name.lastName(normalizedGender);
- switch (r) {
+ switch (variant) {
+ // TODO christopher 21-03-2022: Add possibility to have a prefix together with a suffix
case 0:
prefix = this.faker.name.prefix(gender);
if (prefix) {
@@ -198,22 +205,6 @@ export class Name {
}
/**
- * Generates a random job title.
- *
- * @example
- * faker.name.jobTitle() // 'Global Accounts Engineer'
- */
- jobTitle(): string {
- return (
- this.faker.name.jobDescriptor() +
- ' ' +
- this.faker.name.jobArea() +
- ' ' +
- this.faker.name.jobType()
- );
- }
-
- /**
* Return a random gender.
*
* @param binary Whether to return only binary gender names. Defaults to `false`.
@@ -227,44 +218,30 @@ export class Name {
return this.faker.random.arrayElement(
this.faker.definitions.name.binary_gender
);
- } else {
- return this.faker.random.arrayElement(this.faker.definitions.name.gender);
}
+
+ return this.faker.random.arrayElement(this.faker.definitions.name.gender);
}
/**
* Returns a random name prefix.
*
* @param gender The optional gender to use.
- * Can be either `'male'` (or `0`) or `'female'` (or `1`).
+ * Can be either `'female'` or `'male'`.
*
* @example
* faker.name.prefix() // 'Miss'
* faker.name.prefix('female') // 'Ms.'
- * faker.name.prefix(1) // 'Dr.'
* faker.name.prefix('male') // 'Mr.'
- * faker.name.prefix(0) // 'Mr.'
*/
- prefix(gender?: string | number): string {
- if (
- typeof this.faker.definitions.name.male_prefix !== 'undefined' &&
- typeof this.faker.definitions.name.female_prefix !== 'undefined'
- ) {
- if (typeof gender !== 'number') {
- gender = this.faker.datatype.number(1);
- }
- if (gender === 0) {
- return this.faker.random.arrayElement(
- this.faker.locales[this.faker.locale].name.male_prefix
- );
- } else {
- return this.faker.random.arrayElement(
- this.faker.locales[this.faker.locale].name.female_prefix
- );
- }
- }
+ prefix(gender?: GenderType): string {
+ const { prefix, female_prefix, male_prefix } = this.faker.definitions.name;
- return this.faker.random.arrayElement(this.faker.definitions.name.prefix);
+ return selectDefinition(this.faker, gender, {
+ generic: prefix,
+ female: female_prefix,
+ male: male_prefix,
+ });
}
/**
@@ -274,6 +251,7 @@ export class Name {
* faker.name.suffix() // 'DDS'
*/
suffix(): string {
+ // TODO christopher 21-03-2022: Add female_suffix and male_suffix
return this.faker.random.arrayElement(this.faker.definitions.name.suffix);
}
@@ -298,6 +276,22 @@ export class Name {
}
/**
+ * Generates a random job title.
+ *
+ * @example
+ * faker.name.jobTitle() // 'Global Accounts Engineer'
+ */
+ jobTitle(): string {
+ return (
+ this.faker.name.jobDescriptor() +
+ ' ' +
+ this.faker.name.jobArea() +
+ ' ' +
+ this.faker.name.jobType()
+ );
+ }
+
+ /**
* Generates a random job descriptor.
*
* @example